为什么const lvalue References引用Mutable rvalue References?

use*_*130 5 c++ gcc initialization clang c++11

在C++ 11中,可以使用可变的右值引用初始化const左值引用.然后,rvalue引用的值可以改变,从而产生可见的突变,即const lvalue指的是什么.这是一个例子:

int && rval = 3;
const int & lval = rval;

cout << "lval = " << lval << endl;
cout << "rval = " << rval << endl;

rval ++;

cout << "lval = " << lval << endl;
Run Code Online (Sandbox Code Playgroud)

输出(来自clang 3.2和gcc 4.8.2都使用-std = c ++ 11):

lval = 3
rval = 3
lval = 4
Run Code Online (Sandbox Code Playgroud)

这个的原因是参考物不能通过左值参考修改,但可以通过右值参考修改.但是,我不明白为什么允许const左值引用可变对象.

有人可以解释这个的基本原理,并提供处理这种情况的最佳实践.还有其他类似的例子,其中constness可以被颠覆?

Bil*_*eal 14

但是,我不明白为什么允许const左值引用可变对象

有一个const东西仅供参考意味着你无法通过参考修改的对象.这并不意味着没有人被允许改变对象.

假设你有一个功能:

void f(Foo const& bar);
Run Code Online (Sandbox Code Playgroud)

该函数向调用者声明它不会修改bar.而已.没有什么比这更好的了.它没有提到发生了什么bar,而f被(例如,在另一个线程)执行; 语言无法表达这样的约束.

最后一点:

int && rval = 3;
Run Code Online (Sandbox Code Playgroud)

rval是一个左值.它有一个名称,可以在作业的左侧,正如您的代码清楚地表明的那样.rvalue引用和左值引用之间的区别在于rvalue引用可以绑定到rvalues - 而不是它们本身是rvalues.

这就是给出类似的东西的原因

void foo(unique_ptr<X>&& x)
{
    aVector.emplace_back(x);
}
Run Code Online (Sandbox Code Playgroud)

不编译.x被声明为右值引用,但foo它内部有一个名称,可以在赋值的左侧,并且是左值.将其移动到其他东西需要使用move或类似:

void foo(unique_ptr<X>&& x)
{
    aVector.emplace_back(move(x)); // Ok
}
Run Code Online (Sandbox Code Playgroud)