在 C++11 中,const 左值引用可以用可变右值引用来初始化。右值引用的值然后可以更改,从而对 const 左值所引用的内容产生可见的突变。这是一个例子:
int && rval = 3;
const int & lval = rval;
cout << "lval = " << lval << endl;
cout << "rval = " << rval << endl;
rval ++;
cout << "lval = " << lval << endl;
输出(来自 clang 3.2 和 gcc 4.8.2,均使用 -std=c++11):
lval = 3
rval = 3
lval = 4
我会猜测这样做的原因是不能通过左值引用修改所指对象,但可以通过右值引用修改它。但是,我不明白为什么允许 const 左值引用可变对象。
有人能解释一下这样做的理由并给出处理这种情况的最佳做法吗?另外,是否还有其他类似的例子可以颠覆 constness?
最佳答案
But, I don't understand why a const lvalue is allowed to refer to a mutable object
拥有对某物的const
引用仅意味着您不能通过该引用修改该对象。这并不意味着任何人都不得更改对象。
假设您有一个函数:
void f(Foo const& bar);
该函数向调用者声明它不会修改bar
。而已。仅此而已,仅此而已。它没有说明 f
执行时 bar
发生了什么(例如,在另一个线程中);语言没有办法表达这样的约束。
最后一点:
int && rval = 3;
rval
是一个左值。它有一个名称,可以位于赋值的左侧,正如您的代码清楚地表明的那样。右值引用和左值引用之间的区别在于右值引用可以绑定(bind)到右值——而不是它们本身就是右值。
这就是为什么给出类似的东西
void foo(unique_ptr<X>&& x)
{
aVector.emplace_back(x);
}
不编译。 x
被声明为右值引用,但在 foo
内部它有一个名称并且可以在赋值的左侧,并且是一个左值。将其移动到其他地方需要使用 move
或类似的方法:
void foo(unique_ptr<X>&& x)
{
aVector.emplace_back(move(x)); // Ok
}
关于c++ - 为什么 const 左值引用可以引用可变右值引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20982167/