Search code examples
c++move

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);
  }
};

Solution

  • 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.