2013-06-18 21 views
5

Dopo anni di AS3, sto cercando di imparare di nuovo il C++. I riferimenti mi stanno ancora dando i risultati.Il risultato della funzione non può essere passato come riferimento

considerare le seguenti funzioni:

#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; 
} 

Ora, effettuando le seguenti operazioni:

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

va bene, ma f(get()) produrrà il seguente errore:

"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"

Perché è ? È perché il risultato di una funzione è invisibilmente const?

+0

Per una volta preferisco messaggio di errore di gcc per clang di: 'errore: l'inizializzazione non valido di riferimento non-const di tipo 'std :: list > &' da una temporanea di tipo 'std: : list > '' –

risposta

8

Quando si esegue questa operazione:

f(get()); 

si passa una temporanea std::list<int>-f(). Un temporaneo non può legarsi a un riferimento non const. Quindi puoi risolvere questo problema passando un riferimento a const, dato che non vuoi modificare l'argomento.

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); 
    } 
} 

Si noti che questo richiede l'utilizzo di un const_iterator, dal momento che std::list::begin() const e il metodo corrispondente end() ritorno const_iterator s. In C++ 11 è possibile semplificare questo per

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

o anche

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

Parola chiave: temporaneo –

+0

+1 per la risposta chiara –

-1

Questo è perché il vostro argomento è T &. Era T cont &, funzionava bene.

Alcuni vecchi compilatori hanno fatto funzionare la tua versione come estensione - la regola è in qualche modo arbitraria, ed è lì per evitare sorprese. T & arg indica il tipo OUT (o INOUT), e se le modifiche finiscono temporaneamente, è una sorpresa.

+0

e il problema è? –

0

Si sta restituendo una variabile temporanea std::list dal metodo get(). Questo non funziona perché il tuo argomento non è const per funzionare f.

Problemi correlati