1

Consider the following function:

vector<int> get_vector()
{
    vector<int> xs;
    // Do some stuff to fill the vector with numbers...
    return xs;
}

Would it make sense to write the following instead? The main goal would be to avoid copying the vector when returning it.

vector<int>&& get_vector()
{
    vector<int> xs;
    // Do some stuff to fill the vector with numbers...
    return std::move(xs);
}

Are there any semantic differences other than avoiding a copy?

Barry
  • 286,269
  • 29
  • 621
  • 977
aochagavia
  • 5,887
  • 5
  • 34
  • 53

2 Answers2

10

Yes, there are differences. Consider the following case:

std::vector<int> v = get_vector();

In the first case, we can perform named return value optimization. Which means that the local variable xs is actually going to constructed in place in v. No move will be done here at all. This is as efficient as possible.

In the second case, xs has to be constructed locally so that it can be moved out. NRVO is impossible, so there will be a move. So that is strictly worse.

Now consider the following case:

auto&& v = get_vector();

In the first case, this is OK. get_vector() returns a temporary, which gets bound to the reference and extended for the lifetime of v.

In the second case, we just took a reference to the temporary xs and now have a dangling reference. This is bad.

In summary: always prefer to return your locals by-value. They're already rvalues from the perspective of the caller, so there is no advantage from explicitly making them rvalue references.

Barry
  • 286,269
  • 29
  • 621
  • 977
2

There is no copy. The caller will move it if it can. Besides, in the second one, you're returning a reference to a local, which is bad.