2011-12-22 23 views
17

Naturalmente, questo non verrà compilato:I numeri letterali sono mutabili o no?

int &z = 3; // error: invalid initialization of non-const reference .... 

e questo compilerà:

const int &z = 3; // OK 

Ora, prendere in considerazione:

const int y = 3; 
int && yrr = y; // const error (as you would expect) 
int && yrr = move(y); // const error (as you would expect) 

Ma queste righe successive non compilare per me . Penso che non dovrebbe

int && w = 3; 
int && yrr = move(3); 
void bar(int && x) {x = 10;} 
bar(3); 

Queste ultime due righe non consentono di modificare il valore letterale 3? Qual è la differenza tra 3 e un const int? E infine, c'è qualche pericolo nel 'modificare' i letterali?

(g ++ - 4.6 (GCC) 4.6.2 con -std=gnu++0x -Wall -Wextra)

+1

Per rispondere alla mia stessa domanda: In 'move (3)' forse il 3 viene copiato per primo per creare un int temporaneo sarà distrutto alla fine dell'istruzione. È questa la spiegazione? –

+0

Nella tua seconda affermazione: const &z = 3; manca l'identificatore di tipo. quindi non viene compilato. –

+0

Grazie, @CJohnson, normalmente copio e incollo il codice di lavoro qui. Ma ero incurante di quella fodera! –

risposta

13

La rvalue riferimento letterale 3:

int && w = 3; 

è effettivamente legato a una temporanea che è il risultato della valutazione dell'espressione 3. Non è legato ad alcuni platonici letterale 3.

(tutti i seguenti standard riferimenti sono dal progetto marzo 2011 n3242)

3.10/1 "lvalue e rvalues"

The value of a literal such as 12, 7.3e5, or true is also a prvalue

Poi 8.5. 3 "Riferimenti" dà le regole per come un punto di riferimento è destinato cade attraverso l'ultimo caso, che dice:

Otherwise, a temporary of type “cv1 T1” is created and initialized from the initializer expression using the rules for a non-reference copy-initialization (8.5). The reference is then bound to the temporary.

e dà come un esempio qualcosa di molto simile a ciò che è nel vostro domanda:

double&& rrd = 2; // rrd refers to temporary with value 2.0 
+0

Grazie, ma se fosse vero, allora non dovrebbe funzionare? 'move (3) = 6;' Invece ottengo un errore "* error: usando xvalue (riferimento di rvalue) come lvalue *". È tempo per me di leggere su xvalues ​​e prvalues ​​e tutto ciò di nuovo :-) –

+3

Grazie alla tua risposta, penso di poter rispondere al mio commento di pochi secondi fa. Vedo che 'move (3)' è un valore (chiaramente, è senza nome). Mentre all'interno della mia funzione 'void bar (int && x) {x = 10;}' c'è un nome per 'x'. Questa sembra essere la differenza tra 'x = 6' e' move (3) = 6'. Entrambi sono '&&' ma uno è un lvalue e l'altro no. E questa distinzione è ciò che porta al messaggio di errore per 'move (3) = 6'. –

+0

@Aaron: (Un ritardo) aggiunta al tuo commento: da qualche parte, lo standard specifica che un valore nominale è un lvalue, quindi sì, è esattamente come funziona. :) – Xeo

Problemi correlati