2015-10-23 9 views
30

Jestem nowym do C++ i jestem mylić o tym:Dlaczego referencja const może być ponownie przypisana w instrukcji for?

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

Rozumiem, że const odniesienia r1 nie może być ponownie przydzielony. Ale spójrz na poniższe kody:

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

Dlaczego by tak nie poszło? Oznaczenie stałe r2 jest przypisane dwukrotnie, prawda?

+0

Jest przypisany do v [0], a następnie do v [1], nieprawdaż? –

+6

Dlaczego jest 'for (int k = 0; k <2; k ++) {const int & r1 = v [k];}' allowed? – immibis

+2

@immibis Czytałem to tak, jakby to był [koan] (https: //en.wikipedia.org/wiki/K% C5% 8Dan) i został oświecony. :) – Numeri

Odpowiedz

35

Nie jest przypisany dwa razy. r2 istnieje od początku iteracji (pojedyncza runda nad ciałem pętli) do końca iteracji. r2 w następnej iteracji jest inny obiekt o tej samej nazwie. Każda iteracja ma swój własny numer r2 i każdy z nich jest inicjowany osobno.

+0

Ale 'r2' jest const. Książka, którą przeczytałem, powiedziała, że ​​'r2' jest stałą niskopoziomową, której wartości nie można zmienić. Czy mam rację? –

+0

@XunChenlong Przeczytaj uważniej odpowiedź przed komentarzem. Odpowiedź już zawiera Twój komentarz. :) – hvd

+7

@hvd Och, mam to. Jedna iteracja oznacza jedną pętlę. Myliłem to jako całe oświadczenie. To pomaga. Przepraszam za mój biedny angielski i dziękuję! –

6

wahała oparte for wygląda następująco:

attr (opcja) (range_declaration: range_expression) loop_statement

gdzie range_declaration jest

range_declaration - deklaracja nazwanej zmiennej, której typem jest typ elementu reprezentowanej sekwencji przez range_expression lub odniesienie do tego typu. Często używa automatycznego specyfikatora automatycznego odliczania typu

W każdej iteracji wprowadzana jest nowa deklaracja, odniesienie istnieje tylko do następnej iteracji pętli.

24

Według C++ 11 standardowych [stmt.ranged]:

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

gdzie ¹ v jest vector jest równoważna:

{ 
    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

Oznaczenie const r2 jest przypisany dwa razy, prawda?

Nr Jest nowyr2 zmiennej w każdej iteracji.


¹ zakres oparty for można również stosować z innymi rodzajami zbiorach, takich surowców tablicach. Podana tu równoważność stanowi ogólną równoważność dla std::vector.

Powiązane problemy