2015-10-23 11 views
30

Sono nuovo di C++, e io sono confuso su questo:Perché il riferimento const può essere riassegnato in istruzione for?

vector<int> v = { 1,2 }; 
const int &r1 = v[0]; 
//r1 = v[1]; // compiler will show error. 

Capisco che const riferimento r1 non può essere ri-assegnati. Ma guarda i codici seguenti:

for (const int &r2 : v) cout << r2; 

Perché non dovrebbe andare storto? Il riferimento const r2 viene assegnato due volte, giusto?

+0

È assegnato a v [0], quindi a v [1], non è vero? –

+6

Perché '' (int k = 0; k <2; k ++) {const int & r1 = v [k];} 'consentito? – immibis

+2

@immibis L'ho letto come se fosse un [koan] (https: //en.wikipedia.org/wiki/K% C5% 8Dan), ed è stato illuminato. :) – Numeri

risposta

35

No, non viene assegnato due volte. r2 esiste dall'inizio dell'iterazione (un singolo giro sul corpo del ciclo) fino alla fine dell'iterazione. r2 nella successiva iterazione è un altro oggetto con lo stesso nome. Ogni iterazione ha il proprio r2 e ciascuna di esse viene inizializzata separatamente.

+0

Ma 'r2' è un const. Il libro che ho letto diceva che 'r2' è un const di basso livello, il cui valore non può essere modificato. Ho ragione? –

+0

@XunChenlong Leggere la risposta più attentamente prima di commentare. La risposta riguarda già il tuo commento. :) – hvd

+7

@hvd Oh, ho capito. Un'iterazione significa un ciclo. L'ho scambiato per l'enunciazione definitiva. Aiuta. Scusa per il mio povero inglese e grazie! –

6

Il variava a base for assomiglia a questo:

attr (opzionale) per (range_declaration: range_expression) loop_statement

dove range_declaration è

range_declaration - un dichiarazione di una variabile denominata, il cui tipo è il tipo di elemento della sequenza rappresentata da range_expression, o un riferimento a quel tipo. Utilizza spesso l'identificatore automatico per la deduzione automatica dei tipi

Così ogni iterazione viene introdotta una nuova dichiarazione, il riferimento esiste solo fino alla successiva iterazione del ciclo.

24

Secondo il C++ 11 norma [stmt.ranged]:

for (const int &r2 : v) std::cout << r2; 

dove ¹ v è un vector, è equivalente a:

{ 
    auto && __range = (v); 
    for (auto __begin = __range.begin(), __end = __range.end(); __begin != __end; ++__begin) 
    { 
     const int &r2 = *__begin; // <-- new variable in each iteration 
     std::cout << r2; 
    } 
} 

Demo

Il riferimento const r2 viene assegnato due volte, giusto?

No. C'è un nuovor2 variabile in ogni iterazione.


¹ La gamma basato for può essere utilizzato anche con altri tipi di collezioni, compresi gli array prime. L'equivalenza fornita qui è ciò che l'equivalenza generale diventa per un std::vector.

Problemi correlati