Consider the following function:
Foo foo(Foo x)
{
return x;
}
Will return x invoke the copy constructor or the move constructor? (Let’s leave NRVO aside here.)
To investigate, I wrote a simple Foo class that is only movable but not copyable:
struct Foo
{
Foo() = default;
Foo(const Foo&) = delete;
Foo(Foo&&) = default;
};
If the move constructor were invoked when returning value parameters by value, all should be fine. But the current g++ compiler complains about return x with the following error message:
error: deleted function 'Foo::Foo(const Foo&)'
If I replace return x with return std::move(x), everything is fine. From this I conclude that moving from value parameters must be done explicitly if desired. Is g++’s behavior conforming or not?
If there is a move ctor for Foo, it should be selected.
Function parameters are explicitly excluded from copy elision in return statements (FDIS §12.9p31, first bullet):
However, the next paragraph explicitly brings move ctors back into consideration:
(Emphasis is mine in both quotes.)