jylee
jylee

Reputation: 21

Is it allowed to return a moved object as a const lvalue reference?

Is it allowed to return a moved value as a const lvalue reference?

include<string>
using namespace std;

class C {
private:
  string s;
public:
  const string &release() {
    return move(s);
  }
};

Upvotes: 1

Views: 290

Answers (2)

Anonymous1847
Anonymous1847

Reputation: 2598

No, and I don't see why you would want to. std::move is like a cast, to the rvalue-reference type. The point of rvalue references returned from std::move is for their corresponding values to be moved into another object efficiently, possibly changing the original object in the process. A const lvalue reference would not allow you to change the object, so it can't be moved from.

Upvotes: 0

Guillaume Racicot
Guillaume Racicot

Reputation: 41760

Well, yes but it won't do anything.

The std::move function is just a cast to a rvalue reference. So in effect:

std::string s;
std::move(s); // returns std::string&& to `s`

So it just returns a reference to the object you pass in.

So in your code, you create an rvalue reference to your string s, but you bind that reference to a std::string const&, which cannot be moved from.

You'd be better simply returning the reference directly:

const string &release() {
    return s;
}

Or return by move (using exchange):

std::string release() {
    return std::exchange(s, std::string{});
    // s valid to be reused, thanks to std::exchange
}

The last solution would be to return an rvalue reference, but I wouldn't do that, as it won't guarantee the reference to be moved from.

Upvotes: 2

Related Questions