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

时间:2014-01-07 21:22:57

标签: c++ gcc c++11 initialization clang

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

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左值引用可变对象。

有人可以解释这个的基本原理,并提供处理这种情况的最佳实践。还有,还有其他类似的例子可以破坏常量吗?

1 个答案:

答案 0 :(得分:14)

  

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

对某些内容进行const引用只意味着您无法通过该引用修改该对象。这并不意味着没有人被允许改变对象。

假设你有一个功能:

void f(Foo const& bar);

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

最后一点:

int && rval = 3;

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

这就是给出类似

的原因
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
}