Rai
Rai

Reputation: 1488

std::move in return statements

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

Answers (1)

Vittorio Romeo
Vittorio Romeo

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

Related Questions