c++ - 为什么 const 左值引用可以引用可变右值引用?

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

在 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/

相关文章:

C++ 运算符重载

c - 如何在 gcc -fdump-tree 中使用 "graph"选项?

c++ - std::pair assignment with downcast

c++ - 如何获取 c++0x lambda 表达式的类型?

c++ - 如何在 STL map 内迭代 STL map ?

c++ - GTK 3 如何将一个信号连接到多个小部件?

c - Make 似乎忽略了我的 CFLAGS 和 LDFLAGS

c - realloc 在 vi​​sual studio 中失败,但可以使用 gcc (ntdll.dll)

C++ Pimpl Idiom 使用预先存在的类

c++ - 如何正确解决 const std::string& 和 const std::vector<string>& 歧义?