Non-lvalues come parametri di funzione in C ++

4

Sto leggendo Accelerated C ++ e nel Capitolo 4 viene presentato il concetto di lvalue. C'è un esempio di qualcosa che non dovrebbe funzionare, ma dopo averlo provato personalmente ho scoperto che funziona davvero.

Specificamente affermano che, date queste funzioni:

// return an empty vector
vector<double> emptyvec()
{
  vector<double> v;
  return v;
}

// read things from an input stream into a vector<double>
// (I'm leaving out the function body here because it's irrelevant)
istream &read_things(istream& in, vector<double>& hw);

Questo non dovrebbe essere permesso:

read_stuff( cin, emptyvec() );

Perché emptyvec () è un'espressione e restituisce un oggetto temporaneo (un non-lvalue come lo hanno chiamato nel libro). Tuttavia, questo non solo compila ma effettivamente esegue (Windows 7 / VisualStudio 2010).

Quindi, cosa sta succedendo? Era solo un brutto esempio da parte degli autori, o c'è qualcos'altro che non capisco.

Grazie.

    
posta Alex 24.01.2013 - 16:23
fonte

2 risposte

1

La preoccupazione che le citazioni di libri entrerebbero in gioco se la funzione fosse dichiarata come:

vector<double> &emptyvec()

o

vector<double> *emptyvec()

in quanto restituirebbe un valore temporaneo per riferimento e, nel momento in cui è stato utilizzato il riferimento, il valore a cui si riferiva sarebbe scomparso. Il compilatore dovrebbe emettere un avviso o un errore per questo caso e potresti (ma potrebbe non) vedere una varietà di possibili errori in fase di esecuzione (purtroppo il tipo di errore che potresti vedere potrebbe variare notevolmente).

D'altra parte, se la funzione è effettivamente dichiarata come

vector<double> emptyvec()

il vettore viene restituito in base al valore (ad esempio, una copia del vettore effettivo viene trasformata in qualsiasi punto in cui si memorizza il valore restituito) e il programma dovrebbe funzionare correttamente.

    
risposta data 24.01.2013 - 17:15
fonte
0

È un'estensione del compilatore da parte di Visual Studio. Il codice dovrebbe infatti non essere compilato, e non lo sarà sugli altri principali compilatori come GCC e Clang, poiché un temporaneo non può legarsi a un riferimento mutabile.

    
risposta data 24.01.2013 - 17:52
fonte

Leggi altre domande sui tag