Forma sbagliata:
int &z = 12;
Forma corretta:
int y;
int &r = y;
Domanda :
perché il primo codice è sbagliato? Qual è il " significato " dell'errore nel titolo?
Forma sbagliata:
int &z = 12;
Forma corretta:
int y;
int &r = y;
Domanda :
perché il primo codice è sbagliato? Qual è il " significato " dell'errore nel titolo?
(ostringstream() << "x=" << x).str()
Risposte:
C ++ 03 3.10 / 1 dice: "Ogni espressione è un lvalue o un rvalue." È importante ricordare che la stima contro la stima è una proprietà delle espressioni, non degli oggetti.
Lvalues denomina oggetti che persistono oltre una singola espressione. Ad esempio, obj, *ptr, ptr[index], e ++xsono tutti lvalue.
I valori sono provvisori che evaporano alla fine della piena espressione in cui vivono ("al punto e virgola"). Ad esempio, 1729, x + y, std::string("meow"), e x++sono tutti rvalues.
L'operatore address-of richiede che il suo "operando sia un lvalue". se potessimo prendere l'indirizzo di un'espressione, l'espressione è un lvalue, altrimenti è un rvalue.
&obj; // valid
&12; //invalid
int & = 12;non è valido, lo standard dice che una stringa letterale è un lvalue, altri letterali sono rvalue.
std::string("meow")costruisce un oggetto di tipo std::stringe restituisce un rvalue che designa questo oggetto, 1729non ha effetti collaterali e restituisce un valore 1729 come valore di tipo int.
"Lvalues name objects that persist beyond a single expression."è corretta al 100%. Al contrario, il tuo esempio (const int &)1non è corretto, perché NON è un oggetto "con nome".
int &z = 12;
Sul lato destro, un oggetto temporaneo di tipo intviene creato dall'integrale letterale 12, ma il temporaneo non può essere associato a un riferimento non const. Da qui l'errore. È lo stesso di:
int &z = int(12); //still same error
Perché viene creato un temporaneo? Poiché un riferimento deve fare riferimento a un oggetto nella memoria e affinché un oggetto esista, deve essere prima creato. Poiché l'oggetto è senza nome, è un oggetto temporaneo . Non ha nome. Da questa spiegazione, è diventato abbastanza chiaro perché il secondo caso va bene.
Un oggetto temporaneo può essere associato al riferimento const, il che significa che puoi farlo:
const int &z = 12; //ok
Per ragioni di completezza, vorrei aggiungere che C ++ 11 ha introdotto rvalue-reference, che può legarsi a un oggetto temporaneo. Quindi in C ++ 11, puoi scrivere questo:
int && z = 12; //C+11 only
Nota che c'è &&intead di &. Si noti inoltre che constnon è più necessario, anche se l'oggetto a cui si zlega è un oggetto temporaneo creato dall'integrale letterale 12.
Poiché C ++ 11 ha introdotto rvalue-reference , int&è ora chiamato lvalue-reference .
12è una costante del tempo di compilazione che non può essere modificata a differenza dei dati a cui fa riferimento int&. Quello che puoi fare è
const int& z = 12;
void f( vector<int> const & ), idiomatica per passare un vettore che non deve essere modificato. Il problema ora è che non f( vector<int>(5) )sarebbe corretto e l'utente dovrebbe fornire un sovraccarico diverso, il void f( vector<int> v ) { f(v); }che è banale.
f( vector<int>(5) ), il compilatore crea un temporaneo e quindi lega il riferimento a quello temporaneo, e allo stesso modo se c'era una conversione implicita da 5direttamente. Ciò consente al compilatore di generare una singola firma per la funzione e consente l'implementazione della funzione da parte di un singolo utente. Da lì in poi, un comportamento simile viene definito per il resto degli usi di riferimenti costanti per coerenza.
T const & r = *ptr;qualsiasi uso successivo di rnella funzione può essere sostituito da *ptr, e rnon deve esistere in fase di esecuzione) oppure potrebbe dover essere implementato mantenendo l'indirizzo dell'oggetto che alias (considera di memorizzare un riferimento come membro di un oggetto) - che è implementato come un puntatore con riferimento automatico.
Queste sono le regole del linguaggio C ++:
12) è un "rvalue"int &ri = 12;è mal formatoDevi capire che queste sono regole C ++. Lo sono e basta.
È facile inventare un linguaggio diverso, diciamo C ++ ', con regole leggermente diverse. In C ++ ', sarebbe consentito creare un riferimento non const con un rvalue. Non c'è niente di incoerente o impossibile qui.
Ma consentirebbe un codice rischioso in cui il programmatore potrebbe non ottenere ciò che intendeva, ei progettisti C ++ hanno giustamente deciso di evitare quel rischio.
I riferimenti sono "puntatori nascosti" (non nulli) a cose che possono cambiare (lvalues). Non puoi definirli come una costante. Dovrebbe essere una cosa "variabile".
MODIFICARE::
Sto pensando a
int &x = y;
quasi equivalente a
int* __px = &y;
#define x (*__px)
dove __pxè un nuovo nome, e #define xfunziona solo all'interno del blocco contenente la dichiarazione di xriferimento.
const:)
const