Подтвердить что ты не робот

Почему ссылка 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 назначается дважды, правильно?

4b9b3361

Ответ 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, или ссылкой на этот тип. Часто использует автоматический спецификатор для автоматического вычитания типа

Итак, каждая итерация вводится в новую декларацию, эта ссылка существует только до следующей итерации цикла.