2010-06-30 11 views
22

Mam funkcji,C++ Domyślny argument dla wektora <int> &?

void test(vector<int>& vec); 

Jak mogę ustawić domyślny argument vec? Próbowałem

void test(vector<int>& vec = vector<int>()); 

Ale jest ostrzeżenie "niestandardowe rozszerzenie używane: 'default argumentem': konwersja z 'std :: vector < _Ty>' do 'std :: vector < _Ty> &'"

Czy jest lepszy sposób to zrobić? Zamiast

void test() { 
    vector<int> dummy; 
    test(dummy); 
} 

Pozdrawiam, Voteforpedro

Odpowiedz

43

Czy próbowałeś:

void test(const vector<int>& vec = vector<int>()); 

C++ nie pozwala uzupełnienia tymczasowe być zobowiązany do odniesienia const.

Jeśli naprawdę potrzebujesz mieć wersję vector<int>& (a nie const), możesz zadeklarować instancję statyczną i użyć jej jako wartości domyślnej (czyli nie-tymczasowej).

static vector<int> DEFAULT_VECTOR; 

void test(vector<int>& vec = DEFAULT_VECTOR); 

Ale uwaga, ponieważ DEFAULT_VECTOR będzie (może) być modyfikowany i nie będzie resetowany przy każdym połączeniu! Nie jestem pewien, czy tego właśnie chcesz.


Dzięki stinky472, tutaj jest bezpieczny wątku alternatywa:

Zamiast dostarczać wartość domyślną, równie dobrze można przeciążać test() z wersji zerowej parametru, który wywołuje inną wersję:

void test() 
{ 
    vector<int> vec; 
    test(vec); 
} 
+4

+1 ale myślę, że należy zaznaczyć, że "test" generalnie nie byłby bezpieczny dla wątków, gdyby zmodyfikował ten "DEFAULT_VECTOR". Może to być uciążliwe, ale zdecydowanie zaleciłbym pisanie dwóch funkcji spełniających takie potrzeby (jeden może być użyty ponownie): void test() {vector temp; test (temp); } – stinky472

+0

@ stinky472: Dzięki, zaktualizowałem moją odpowiedź. – ereOn

+1

Na marginesie, istnieje hacky sposób na uzyskanie odniesienia do tymczasowego, jeśli możesz użyć na nim metody, która zwraca takie odniesienie do siebie ... np. 'operator ='. Tak więc, 'void test (wektor & vec = wektor () .operator = (wektor ()));' powinien działać (czas życia tymczasowego nie ma tutaj wpływu i pozostanie wystarczający do obsłużenia połączenia). Ale proszę, nie rób tego :) –

7

Uważam za wątpliwe, czy argument odniesienia o wartości innej niż const ma wartość domyślną. Co to ma znaczyć?

Powszechnie, funkcja przyjmująca wartość inną niż const oznacza "Mogę zmienić argument". Jeśli argumentem jest opcjonalnie, dlaczego nie przekazać wskaźnik (non-const)? W ten sposób, gdy osoby dzwoniące nie chcą przekazywać argumentów, mogą przekazać NULL.
(Patrz here uzyskać więcej informacji o tym, jak przekazywać argumenty funkcji.)

Edycja: No i oczywiście jest też przeciążenia. Po prostu dodaj kolejne przeciążenie, które nie przyjmuje tego argumentu.

+0

Masz wątpliwości? – Puppy

+3

@DeadMG: Czy odwołujesz się do mojego podrzędnego podzespołu gramatyki? – sbi

+1

Czy zrobiłbym coś takiego? – Puppy

3

Nie możemy zainicjować zmienionych odniesień do tymczasowych. Mają na to tylko odniesienia do stałych.Co jesteś po to jest najbardziej prawdopodobne:

void test(const vector<int>& vec = vector<int>()); 

Oprócz unikania niezdefiniowanej zachowanie, to największy sens logicznie iz perspektywy const-poprawności. Jeśli chciałbyś, aby "test" modyfikuje oryginalny wektor, który jest do niego przekazywany, nie byłbyś w stanie rozsądnie podać wartości domyślnej. Zatem oczywiste jest, że używasz tutaj "vec" w celach tylko do odczytu i dlatego powinno to być odniesienie do stałej.

+2

Nie można zainicjować zmiennych referencji bezpośrednio do temporaries, period. Tymczasowy nie będzie wiązał się z referencją do niestanowiącą końca - jeśli spróbujesz, nie jest to U.B., to źle sformułowane wejście (np. Błąd kompilatora). VC++ pozwala ci to zrobić, ale słusznie zauważa, że ​​jest to rozszerzenie języka. –

+0

@Pavel ah dobry punkt! Widziałem paskudne kompilatory, które dopuszczały takie zachowanie jak MSVC i wcześniejsze wersje CodeWarrior, w których kod został zbudowany, ale uległy awarii. Zmodyfikuję stanowisko odpowiednio dla dokładności. Dziękuję za wskazanie. – stinky472

-1

Wiem, że to pytanie zostało zadane w 2010 roku, ale dla C++ 11 można to zrobić tak:

void test(vector<int>& vec = {}) { 
     // Awesome code here 
} 

Jak wskazano w this answer.

+0

To ma to samo znaczenie co 'void test (wektor & vec = wektor ());' jak w pytaniu, które jest niedozwolone z powodu próby związania tymczasowego z referencją nie będącą stałą. W odpowiedzi, do której prowadzi link, nie jest to odniesienie. –

Powiązane problemy