Czy jest możliwe nadanie wartości domyślnej parametrowi funkcji, gdy przekazujemy parametr przez odniesienie? w C ++
Na przykład, gdy próbuję zadeklarować funkcję taką jak:
virtual const ULONG Write(ULONG &State = 0, bool sequence = true);
Kiedy to robię, wyświetla błąd:
błąd C2440: „domyślny argument”: nie można przekonwertować z „const int” na „unsigned long” & „Odwołanie, które nie jest do„ const ”, nie może być powiązane z wartością inną niż l
c++
pass-by-reference
default-value
Drew Noakes
źródło
źródło
WxWidgets style guide says "don't use templates" and they have good reasons
<- screw std :: vector, mówięOdpowiedzi:
Możesz to zrobić dla odwołania do stałej, ale nie dla odniesienia innego niż stała. Dzieje się tak, ponieważ C ++ nie pozwala na tymczasowe (w tym przypadku wartość domyślną) powiązanie z odwołaniem niebędącym stałym.
Jednym ze sposobów byłoby użycie rzeczywistej instancji jako domyślnej:
ale ma to bardzo ograniczone praktyczne zastosowanie.
źródło
Zostało to już powiedziane w jednym z bezpośrednich komentarzy do Twojej odpowiedzi, ale tylko po to, aby oficjalnie to stwierdzić. To, czego chcesz użyć, to przeciążenie:
Używanie przeciążeń funkcji ma również dodatkowe zalety. Po pierwsze, możesz ustawić domyślny dowolny argument:
Możliwe jest również przedefiniowanie domyślnych argumentów na funkcje wirtualne w klasie pochodnej, co pozwala uniknąć przeciążenia:
Jest tylko jedna sytuacja, w której naprawdę trzeba użyć wartości domyślnej, a jest to konstruktor. Nie jest możliwe wywołanie jednego konstruktora z innego, więc ta technika nie działa w tym przypadku.
źródło
d.f2(); // f2(int) called with '0' b.f2(); // f2(int) called with '0'
Wciąż istnieje stary sposób C na dostarczanie opcjonalnych argumentów: wskaźnik, który może mieć wartość NULL, gdy nie jest obecny:
źródło
Ten mały szablon pomoże ci:
Wtedy będziesz mógł:
źródło
ByRef
żywo, jeśli chodzi o pamięć? Czy nie jest to obiekt tymczasowy, który zostałby zniszczony po opuszczeniu jakiegoś zakresu (jak konstruktor)?Nie, to niemożliwe.
Przekazywanie przez odwołanie oznacza, że funkcja może zmienić wartość parametru. Jeśli parametr nie jest dostarczany przez obiekt wywołujący i pochodzi z domyślnej stałej, co ma zmienić funkcja?
źródło
Istnieją dwa powody, dla których należy przekazać argument przez odwołanie: (1) ze względu na wydajność (w takim przypadku chcesz przekazać przez odwołanie do stałej) i (2), ponieważ potrzebujesz możliwości zmiany wartości argumentu wewnątrz funkcji.
Wątpię, czy zbyt długi czas poświęcony nowoczesnym architekturom zbytnio Cię spowolni. Zakładam więc, że zamierzasz zmienić wartość
State
wewnątrz metody. Kompilator narzeka, ponieważ stałej0
nie można zmienić, ponieważ jest to wartość r („non-lvalue” w komunikacie o błędzie) i niezmienna (const
w komunikacie o błędzie).Mówiąc najprościej, potrzebujesz metody, która może zmienić przekazany argument, ale domyślnie chcesz przekazać argument, którego nie można zmienić.
Inaczej mówiąc, elementy niebędące
const
referencjami muszą odnosić się do rzeczywistych zmiennych. Wartość domyślna funkcji signature (0
) nie jest rzeczywistą zmienną. Masz ten sam problem, co:Jeśli w rzeczywistości nie zamierzasz zmieniać
State
w metodzie, możesz po prostu zmienić ją naconst ULONG&
. Ale nie odniesiesz z tego dużej korzyści z wydajności, więc poleciłbym zmienić to na nie-odniesienieULONG
. Zauważyłem, że zwracasz już aULONG
, i mam podstępne podejrzenie, że jego wartość jest wartościąState
po wszelkich potrzebnych modyfikacjach. W takim przypadku po prostu zadeklarowałbym metodę jako taką:Oczywiście nie jestem pewien, co piszesz ani gdzie. Ale to kolejne pytanie na inny czas.
źródło
Nie można użyć stałego literału dla parametru domyślnego z tego samego powodu, dla którego nie można użyć go jako parametru do wywołania funkcji. Wartości odniesienia muszą mieć adres, stałe wartości odniesienia nie muszą (tj. Mogą to być wartości r lub stałe literały).
Upewnij się, że wartość domyślna ma adres i wszystko w porządku.
Użyłem tego wzorca kilka razy, gdy miałem parametr, który mógł być zmienną lub zerową. W takim przypadku zwykłym podejściem jest podanie przez użytkownika wskaźnika. Przekazują wskaźnik NULL, jeśli nie chcą, abyś wpisał wartość. Lubię podejście zerowe. Ułatwia życie dzwoniącym bez strasznego komplikowania kodu wywołującego.
źródło
Myślę, że nie, a powodem jest to, że wartości domyślne są oceniane jako stałe, a wartości przekazywane przez odniesienie muszą być w stanie zmienić, chyba że zadeklarujesz również, że jest to stałe odniesienie.
źródło
Innym sposobem może być:
wtedy możliwe są następujące połączenia:
źródło
źródło
W przypadku OO ... Powiedzieć, że dana klasa ma i „Domyślna” oznacza, że ta wartość domyślna (wartość) musi być zadeklarowana odpowiednio, a następnie może być USD jako parametr domyślny, np .:
O Twojej metodzie ...
To rozwiązanie jest całkiem odpowiednie, ponieważ w tym przypadku „Globalna domyślna paginacja” jest pojedynczą wartością „odniesienia”. Będziesz mieć również możliwość zmiany wartości domyślnych w czasie wykonywania, takich jak konfiguracja „na poziomie globalnym”, np. Preferencje nawigacji po stronicowaniu użytkowników itp.
źródło
Jest to możliwe z kwalifikatorem const dla State:
źródło
źródło
Jest na to dość brudna sztuczka:
W takim przypadku musisz zadzwonić za pomocą
std::move
:To tylko zabawne obejście, całkowicie nie polecam używania go w prawdziwym kodzie!
źródło
Mam obejście tego problemu, zobacz następujący przykład dotyczący wartości domyślnej dla
int&
:Można to zrobić za każdym trywialny typu danych, które chcesz, takich jak
bool
,double
...źródło
Zdefiniuj 2 funkcje przeciążenia.
źródło
Odpowiedź jest dość prosta i nie jestem zbyt dobry w wyjaśnianiu, ale jeśli chcesz przekazać domyślną wartość do parametru innego niż const, który prawdopodobnie zostanie zmodyfikowany w tej funkcji, użyj go w następujący sposób:
źródło