Почему ссылка const может быть переопределена в for-statement?
Я новичок в С++, и я смущен этим:
vector<int> v = { 1,2 };
const int &r1 = v[0];
//r1 = v[1]; // compiler will show error.
Я понимаю, что ссылка const r1
не может быть повторно назначена. Но посмотрите на коды ниже:
for (const int &r2 : v) cout << r2;
Почему бы не пойти не так? Ссылка const r2
назначается дважды, правильно?
Ответы
Ответ 1
Нет, он не назначается дважды. r2
существует с начала итерации (один раунд над телом цикла) до конца итерации. r2
в следующей итерации - другой объект с тем же именем. Каждая итерация имеет свой собственный r2
, и каждый из них инициализируется отдельно.
Ответ 2
В соответствии со стандартом С++ 11 [stmt.ranged]:
for (const int &r2 : v) std::cout << r2;
где ¹ v
является a vector
, эквивалентно:
{
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;
}
}
Демо
Ссылка const r2
назначается дважды, справа?
Нет. В каждой итерации есть новая переменная r2
.
¹ Диапазон на основе for
также может использоваться с другими видами коллекций, включая необработанные массивы. Приведенная здесь эквивалентность - это общая эквивалентность при a std::vector
.
Ответ 3
for
на основе диапазона выглядит следующим образом:
attr (необязательно) для (range_declaration: range_expression) loop_statement
где range_declaration
range_declaration - объявление именованной переменной, тип которой является типом элемента последовательности, представленной range_expression, или ссылкой на этот тип. Часто использует автоматический спецификатор для автоматического вычитания типа
Итак, каждая итерация вводится в новую декларацию, эта ссылка существует только до следующей итерации цикла.