Imagine you have the following code snippet:
struct S
{
S() = default();
S(S const&){std::cout << "copy ctor" << '\n';};
S& operator=(S const&) { std::cout << "copy assignment" << '\n'; return *this; }
~S();
};
S createS(){return s{};}
int main()
{
S s{};
s = createS();
}
Although it is against the rule of five, what happens in the assignment of s
in the main()
function? createS()
returns an r-value. So, the compiler will search for a move assignment operator, and since it is not generated automatically and deleted, it will fall back to the copy assignment operator. However, an r-value semantically does not bind with a copy operation, since it does not have an identifier and cannot be reused (to my understanding).
My question is, how does the assignment operator handle this situation and distinguish between r-value and l-value?
My question is, how does the assignment operator handle this situation and distinguish between r-value and l-value?
It doesn't need to differentiate. Your copy assignment operator takes a const reference as input, and a const reference can bind to an rvalue (a non-const reference cannot). The temporary S
object will not be destroyed until after the assignment is complete, so the reference is perfectly valid.