#include <iostream>
class MyClass
{
public:
MyClass() = default;
MyClass& operator=(const MyClass& other) { std::cout << "copy\n"; i = other.i; return *this; }
MyClass& operator=(MyClass&& other) noexcept { std::cout << "Move\n"; i = other.i; return *this; }
MyClass(const MyClass& other) { std::cout << "copy construct\n"; i = other.i; };
int i = 10;
};
MyClass function()
{
MyClass c{};
return c;
}
int main()
{
MyClass c1;
MyClass c2;
c1 = function();
}
Why does the line c1 = function();
call copy constructor and move assignment operator? Where exactly does copy construction happen? I can understand that the contents of local variable c
gets moved since it's in a local scope and it's going to be destroyed anyway. But where does copy construction happen?
And if I change function to:
MyClass function()
{
return MyClass{};
}
It only calls move constructor.
CodePudding user response:
I can understand that the contents of local variable c gets moved
This is incorrect. The declared class does not have a move constructor, so it cannot be moved, only copied into the caller's context. Which is what happens. That's step 1. Step 2 invokes the move-assignment operator, in the caller's context, to move the temporary into c1
.
Note that even if the class has a move constructor, this is a named return value, which does not have guaranteed copy elision. So the object might still end up moved, and assigned. And if copy elision takes place the object will still be move-assigned.