struct Test {
int field = 30;
Test() { cout << "In ctor" << endl; }
Test(const Test &other) { field = other.field; cout << "In copy ctor" << endl; }
Test(Test &&other) { field = other.field; cout << "In move ctor" << endl; }
Test &operator=(const Test &other) { field = other.field; cout << "In copy assignment" << endl; return *this; }
Test &operator=(Test &&other) { field = other.field; cout << "In move assignment" << endl; return *this; }
~Test() { cout << "In dtor" << endl; }
};
Test get_test() {
Test t;
return t;
}
int main() {
Test t2 = get_test();
}
I think this is the canonical NRVO example. I'm compiling with -fno-elide-constructors
and I see that the following are called: ctor, move ctor, dtor, dtor.
So the first ctor call corresponds to the line Test t;
, the move ctor is constructing the t2
in main
, then the temporary that is returned from get_test
is destroyed, then the t2
in main
is destroyed.
What I don't understand is: shouldn't there be a copy ctor invocation when returning by value? That is, I thought that get_test
should be making a copy of t
and then this copy is moved into t2
. It seems like t
is moved into t2
right away.