2012-05-10 30 views
5

Czy ten kod jest prawidłowy?Czas życia zmiennej tymczasowej C++

int foo() 
{ 
    std::vector<std::string>& v = std::vector<std::string>(5, "X"); 

    // Do something silly... 

    return 42; 
} 

Z jakiegoś powodu myślałam, że tymczasowy std::vector obiekt (prawo od znaku przypisania) powinny być zniszczone zaraz po jego budowa (czyniąc odniesienia nieprawidłowy).

Jednak debugowanie dowodzi, że się mylę i, cóż, zdałem sobie sprawę, że nie do końca rozumiem, dlaczego zmienna tymczasowa jest niszczona po powrocie funkcji .


Chyba mam silne niezrozumienie czymś fundamentalnym, więc proszę mnie oświecić :)

+0

Kiedy mówisz "debugowanie dowodzi, że się mylę", co dokładnie masz na myśli? –

Odpowiedz

8

Kod masz pokazane jest nielegalne – uzupełnienia tymczasowe może wiązać się jedynie do odesłania rvalue lub const referencje lwartości.

VC++ zdarza się, aby zezwolić na to jako rozszerzenie (i daje to a level 4 warning).

+1

gcc narzeka ładnie na ten temat: 'błąd: niepoprawna inicjalizacja niezwiązanej referencji typu 'std :: wektor , std :: allocator >, std :: allocator < std :: basic_string , std :: allocator >>> & "z tymczasowego typu 'std :: vector , std :: allocator >, std :: allocator , std :: allocator >>> ' – Scottymac

+0

Dziękuję, nie wiedziałeś o tym rozszerzeniu * (i, no, powinien" ve tried 'gcc'). * –

+2

@ Yippie-Kai-Yay: Wtedy powinieneś budować z włączonymi ostrzeżeniami 4 poziomu. ; -] – ildjarn

2

Masz odwołanie do obiektu przydzielonego. Działa przez "zwykłe szczęście" (patrz Język programowania w C++, sekcja 10.4.10 Obiekty tymczasowe). Nie możesz zagwarantować, że zadziała w każdym kompilatorze.

Można tylko upewnić się, że czas życia tymczasowego jest dłuższy, jeśli jest powiązany z numerem referencyjnym const.

+2

To nie jest zwykłe szczęście w tym przypadku, jest to rozszerzenie języka dostarczone przez kompilator, którego używa OP. – ildjarn

+0

@ildjarn Po prostu cytuję Stroustrupa z przymrużeniem oka. Chodzi o to, że jest nieprzenośny/nielegalny/niewiarygodny lub jakkolwiek chcesz go nazwać. – frozenkoi

+3

Nie jest przenośny, zgodził się, ale nie jest również nielegalny; standard C++ (§1.4/8) wyraźnie zezwala na rozszerzenia językowe, o ile rozszerzenie nie wpływa na zachowanie dobrze sformułowanego kodu, a kompilator wydaje komunikat diagnostyczny (liczba ostrzeżeń). – ildjarn

3

Normalny czas życia tymczasowy to do końca pełnego wyrażenia , w którym został utworzony; niekoniecznie jest niszczony natychmiast po użyciu. Jeśli tymczasowy jest używany do zainicjowania odwołania, jego czas życia jest wydłużony, aby pasował do odwołania (z znaczącym wyjątkiem tymczasowego utworzonego na liście inicjalizacyjnej konstruktora ).

Oczywiście Twój kod jest nielegalny; jeśli odwołanie ma wartość inną niż const, to można zainicjować tylko z pewnego rodzaju lwartością. Ale jeśli byłby to legalny (i przynajmniej jeden kompilator akceptuje to), czas życia powinien być przedłużony o , aby pasował do odniesienia.

Powiązane problemy