inizializzazione riferimento in C ++
-
22-09-2019 - |
Domanda
Qualcuno può spiegare a me perché non v'è una differenza tra queste due affermazioni?
class A{};
const A& a = A(); // correct
A& b = A(); // wrong
Si dice
inizializzazione valido di riferimento non const di tipo A&
da un temporaneo di tipo A
Perché const
importa qui?
Soluzione
riferimenti non edificati devono essere inizializzati con L-valori. Se li si potrebbe inizializzare con temporanei, allora che cosa avrebbe fatto il seguente?
int& foo = 5;
foo = 6; // ?!
riferimenti const
hanno la proprietà speciale che si estendono la vita del direttore di gara, e dal momento che sono const
, non v'è alcuna possibilità che si tenta di modificare qualcosa che non si siede in memoria. Ad esempio:
const int& foo = 5;
foo = 6; // not allowed, because foo is const.
Ricordate che i riferimenti in realtà hanno per riferirsi a qualcosa, non solo le variabili temporanee. Ad esempio, il seguente è valido:
int foo = 5;
int& bar = foo;
bar = 6;
assert(foo == 6);
Altri suggerimenti
La terminologia su questo è un po 'di confusione; si consiglia di ricerca di loro un po 'più. Ecco la risposta breve però:
Si sta assegnando un oggetto temporaneo (il risultato della chiamata di costruzione della classe) a una variabile. Un oggetto temporaneo è un valore R. Non è possibile assegnare un valore di R a un riferimento non-const.
Hai il permesso di assegnare un valore di R a un riferimento const, anche se la logica per permettere è abbastanza oscura.
Nel linguaggio C ++ è illegale per fissare un riferimento non const a un rvalue, mentre è perfettamente OK per collegare un riferimento const ad un rvalue. Ad esempio, questo è legale
const int& r = 5;
mentre questo non è
int &r = 5; // ERROR
Un oggetto temporaneo di tipo A
restituito dal A()
espressione è un rvalue, quindi la regola di cui sopra si applica nel tuo caso pure.
Per una temporanea / rvalue, si può avere solo un riferimento const.
Si può avere un riferimento non const a un non-temporanea / lvalue.
A a;
A& b = a;
Credo che la ragione per la quale è quello di rafforzare il fatto che un rvalue è temporaneo in quanto v'è poco valore di essere in grado di modificare qualcosa che sta per scomparire momentaneamente.
A causa dello standard dice così:
§8.5.3.5 ... Altrimenti, il riferimento deve essere un valore assegnabile riferimento a un tipo const non volatile ...
Tuttavia, se si vuole molto, si può ottenere:
#include <iostream>
int main()
{
const int & cr=5;
int & r=const_cast<int &>(cr);
r=6;
std::cout<<r;
}
// outputs 6 with c++/clang++, Debian 8, amd64
Ma essere consapevoli del fatto che la cr costante presunta non è const più, troppo, e si incorre comportamento indefinito. (§1.9 (4))
Come suggerito dal codice di cui sopra, non v'è alcuna ragione tecnica per la differenza. Piuttosto, i progettisti hanno avuto incubi ciò che gli utenti avrebbero fatto con i riferimenti non-const per provvisori.