Reputation: 1488
I've been paying close attention to the advice never to write std::move
in a return statement, for example. Except there are some edge cases, for example.
I believe the following is another simple example of where std::move
may be worthwhile - did I miss something? But I'm not sure why, and will that change in a future C++?
#include <iostream>
struct A
{
};
struct C
{
};
struct B
{
B(const A&, const C&) { std::cout << "B was copied\n"; }
B(A&&, C&&) { std::cout << "B was moved\n"; }
};
B f()
{
A a;
C c;
//return {a, c}; // Gives "B was copied"
return {std::move(a), std::move(c)}; // Gives "B was moved"
}
int main() {
f();
return 0;
}
Upvotes: 1
Views: 803
Reputation: 93264
return {std::move(a), std::move(c)}
is equivalent to
return B{std::move(a), std::move(c)}
You're basically invoking B::B(A&&, C&&)
instead of the version taking const&
references. This has nothing to do with moving a return value.
The return value of the function is the temporary instance of B
, which is a prvalue. It C++17, it will benefit from "guaranteed copy elision". Before C++17, it will be RVOd or moved into its target.
Upvotes: 7