为什么可以在 for 语句中重新分配引用常量

Why reference const can be re-assigned in for-statement?

本文关键字:分配 常量 引用 新分配 for 语句 为什么      更新时间:2023-10-16

我是C++新手,我对此感到困惑:

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

我知道引用常量r1不能重新分配。但是看看下面的代码:

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

为什么不会出错呢?引用常量r2被分配了两次,对吧?

不,它没有分配两次。 r2从迭代开始(循环体上的单个倒圆角(一直存在,直到迭代结束。 r2在下一个迭代中是另一个同名的对象。每个迭代都有自己的r2并且每个迭代都是单独初始化的。

根据 C++11 标准 [stmt.ranged]

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

其中 ¹ vvector ,等效于:

{
    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;
    }
}

演示

引用常量r2被分配了两次,对吧?

不。每次迭代中都有一个新的r2变量。


¹ 基于范围的for还可以与其他类型的集合一起使用,包括原始数组。这里给出的等价就是std::vector的一般等价。

基于范围的for如下所示:

( range_declaration : range_expression ( 的 attr(可选( loop_statement

range_declaration在哪里

range_declaration - 命名变量的声明,其类型是 range_expression 表示的序列元素的类型,或对该类型的引用。经常使用自动说明符进行自动类型扣除

因此,每次迭代都会引入一个新声明,该引用仅在下一次循环迭代之前存在。