2013-06-18 12 views
5

Po latach AS3, staram się ponownie nauczyć C++. Referencje wciąż mi pasują.Wynik funkcji nie może być przekazany jako odniesienie

Rozważmy następujące funkcje:

#include <cstdio> 
#include <list> 

void f(std::list<int>& v) { 
    for (std::list<int>::iterator i = v.begin(); i != v.end(); ++i) 
    printf("Hello %d\n", *i); 
} 

std::list<int> get(void) { 
    std::list<int> list; 
    list.push_back(0); 
    return list; 
} 

Teraz, wykonując następujące czynności:

std::list<int> l = get(); 
f(l); 

jest w porządku, ale f(get()) przyniesie następujący błąd:

"no matching function for call to 'f'", "candidate function not viable: no known conversion from `'std::list<int>' to 'std::list<int>&' for 1st argument"

Dlaczego jest to, że ? Czy to dlatego, że wynik funkcji jest niewidoczny: const?

+0

Tym razem wolę wiadomość błędu gcc od klang: 'błąd: niepoprawna inicjalizacja nie-const referencji typu 'std :: list > &' from tymczasowy typ 'std: : lista > '' –

Odpowiedz

8

Kiedy to zrobić:

f(get()); 

przekazać tymczasowy std::list<int> do f(). Plik tymczasowy nie może się połączyć z referencją bez stałych. Możesz to naprawić, przekazując odniesienie const, ponieważ nie chcesz modyfikować argumentu.

void f(const std::list<int>& v) 
{ // ^^^^^ 
    for (std::list<int>::const_iterator i = v.begin(); i != v.end(); ++i) 
    { //     ^^^^^^^^^^^^^^ 
    printf("Hello %d\n", *i); 
    } 
} 

Zauważ, że wymaga to, że używasz const_iterator, ponieważ std::list::begin() const i odpowiadające end() Sposób powrotu const_iterator ów. W C++ 11 można uprościć to

for (auto i = v.begin(); i != v.end(); ++i) 
    ... 

lub nawet

for (const auto& i : v) 
    std::cout << i << "\n"; 
+1

Słowo kluczowe: tymczasowy –

+0

+1 dla jasnej odpowiedzi –

-1

To dlatego, że twój argument jest T &. To było T &, działało dobrze.

Niektóre stare kompilatory sprawiły, że twoja wersja działa jako rozszerzenie - reguła jest nieco arbitralna i ma na celu uniknięcie zaskoczenia. T & arg oznacza typ OUT (lub INOUT), a jeśli modyfikacje zakończą się tymczasowo, jest to niespodzianka.

+0

i problem jest? –

0

Zwracasz tymczasową zmienną std::list z metody get(). To nie działa, ponieważ twój argument nie jest const do funkcji f.

Powiązane problemy