Passing the rvalue rtByValue()
to a function that expects an lvalue reference doesn't work because this would require the lvalue reference argument to be initialized from an rvalue. §8.5.3/5 describes how lvalue references can be initialized – I won't quote it in full, but it basically says that an lvalue reference can be initialized
- either from another lvalue reference
- or something that can be converted to an lvalue reference of an intermediary type
- or from an rvalue, but only if the lvalue reference we initialize is a const-reference
Since the argument we need to initialize is not a const-reference, none of this applies.
On the other hand,
rtByValue() = aa;
i.e., assigning to a temporary object, is possible because of:
(§3.10/5) An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [ Example: a member function called for an object (9.3) can modify the object. — end example ]
So this works only because A
is of class-type, and the (implicitly defined) assignment operator is a member function. (See this related question for further details.)
(So, if rtByValue()
were to return, for example, an int
, then the assignment wouldn't work.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…