Why reference can not capture temporary while const ref and rval ref can [duplicate]

风格不统一 提交于 2019-12-22 17:40:13

问题


Why reference can not capture temporary value while const reference and rvalue reference can capture and prolong object life. In other words while two first lines are legal but third not:

const string &a = string("a");
string &&b = string("b");
string &c = string("c"); // why illegal?

回答1:


Quoting from N1377

Bjarne in his excellent text "The Design and Evolution of C++" discusses the motivation for prohibiting the binding of an rvalue to a non-const reference in section 3.7. The following example is shown:

void incr(int& rr) {rr++;}

void g()
{
    double ss = 1;
    incr(ss);
}

ss is not incremented, as a temporary int must be created to pass to incr(). The authors want to say right up front that we agree with this analysis 100%. Howard was even bitten by this "bug" once with an early compiler. It took him forever to track down what was going on (in that case it was an implicit conversion from float to double that created the temporary).

This rationale (for not binding rvalues to non-const (lvalue) references) held from the dawn of C++, up until C++11 (2011). However the same rationale does not apply to lvalue references to const:

It is "safe" to bind a temporary to an lvalue reference to const because the compiler will tell you if you accidentally make a "useless" modification to this temporary.

So why is it "safe" to bind an rvalue to an rvalue reference?

Again quoting from N1377:

Having said that, we would like to add: You don't ever want to bind a temporary to a non-const reference ... except when you do.

A non-const reference is not always intended to be an "out" parameter. Consider:

template <class T>
class auto_ptr
{
public:
    auto_ptr(auto_ptr& a);
    ...
};

The "copy" constructor takes a non-const reference named "a". But the modification of "a" is not the primary goal of this function. The primary goal is to construct a new auto_ptr by pilfering "a". If "a" happens to refer to an rvalue, this is not a logical error!

In summary, sometimes you want to modify an rvalue, and sometimes you don't. The different types of references allow the programmer to tell the compiler which situation they are in.

The bindings in your question are a logical conclusion of the bindings motivated by N1377.

The move semantics proposal did put effort into coming up with a solution that did not require language changes (i.e. the introduction of the rvalue reference). However library only solutions were unsatisfactory as the resulting syntax for building things like move constructors was overly complex.



来源:https://stackoverflow.com/questions/25025538/why-reference-can-not-capture-temporary-while-const-ref-and-rval-ref-can

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