In the C programming language, rvalues (right-hand values) typically cannot be used as lvalues (left-hand values). However, there are exceptions to this rule, as illustrated by the following code:
<code class="cpp">class Y { public: explicit Y(size_t num = 0) {} }; int main() { Y(1) = Y(0); // WHAT?!? return 0; }</code>
Surprisingly, this code compiles successfully, even though the object returned by the constructor Y(1) is an rvalue. This article explores the reasons behind this unexpected behavior.
The key to understanding why this code is valid lies in the concept of synthesized member functions. For classes that do not explicitly define an assignment operator, the compiler generates a default assignment operator. This default operator is a member function that takes a reference to an object of the same class as its parameter.
In the example above, the assignment operator for class Y is synthesized as follows:
<code class="cpp">Y& Y::operator=(const Y& other);</code>
Notably, this synthesized assignment operator is a non-const member function. This means that it can be applied to both lvalues (referenced objects) and rvalues (unreferenced objects).
When an object is created using a constructor that returns an rvalue, the compiler generates a temporary object in memory. This temporary object is automatically destroyed at the end of the statement in which it was created. However, in the case where the constructor returns an rvalue of class type, the synthesized assignment operator can extend the lifetime of the temporary object.
The assignment statement Y(1) = Y(0); is syntactic sugar for the following code:
<code class="cpp">Y(1).operator=(Y(0));</code>
As we have established, the synthesized assignment operator operator= for class Y is a non-const member function, meaning it can be applied to an rvalue. Therefore, the compiler can interpret the assignment statement as an assignment to the temporary object created by the constructor Y(1).
Contrary to what is typically expected, it is possible to assign to an rvalue of class type in C because the compiler synthesizes non-const assignment operators for classes without an explicitly defined assignment operator. These synthesized assignment operators extend the lifetime of temporary objects created by constructors, allowing assignments to rvalues.
The above is the detailed content of Can You Assign to an Rvalue of Class Type in C ?. For more information, please follow other related articles on the PHP Chinese website!