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)