Why Can const lvalue References Refer to Mutable rvalue References?

会有一股神秘感。 提交于 2020-01-02 04:10:09

问题


In C++11 a const lvalue reference can be initialized with a mutable rvalue reference. The value referred to by the rvalue can then change producing a visible mutation to what the const lvalue is referring to. Here is an example:

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

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

rval ++;

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

Output (from clang 3.2 and gcc 4.8.2 both with -std=c++11):

lval = 3
rval = 3
lval = 4

I would guess the reason for this is that the referent cannot be modified through the lvalue reference but it can be modified through the rvalue reference. But, I don't understand why a const lvalue is allowed to refer to a mutable object.

Can someone explain the rationale for this and give best practices for when dealing with such a situation. Also, are there other similar examples where constness can be subverted?


回答1:


But, I don't understand why a const lvalue is allowed to refer to a mutable object

Having a const reference to something only means that you can't modify the object through that reference. It doesn't mean that nobody is allowed to change the object ever.

Let's say you have a function:

void f(Foo const& bar);

The function is declaring to the caller that it will not modify bar. That's it. Nothing more than that, nothing less than that. It says nothing about what happens to bar while f is executing (e.g. in another thread); the language doesn't have a way to express constraints like that.

One last bit here:

int && rval = 3;

rval is an lvalue. It has a name and can be on the left side of an assignment, as your code clearly demonstrates. The difference between an rvalue reference and an lvalue reference is that rvalue references can bind to rvalues -- not that they themselves are rvalues.

This is why given something like

void foo(unique_ptr<X>&& x)
{
    aVector.emplace_back(x);
}

does not compile. x is declared as an rvalue reference, but inside foo it has a name and can be on the left side of an assignment, and is an lvalue. Moving it into something else requires using move or similar:

void foo(unique_ptr<X>&& x)
{
    aVector.emplace_back(move(x)); // Ok
}


来源:https://stackoverflow.com/questions/20982167/why-can-const-lvalue-references-refer-to-mutable-rvalue-references

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!