second grade move

c++, c++11

Solution

In C++11 you can overload methods on wether or not the `this`-pointer is a rvalue:

T value() &&; //Will only be called if the object is a mutable rvalue
T value() const &; //Will only be called if the object is an lvalue

Note that according to `13.1.2 [over.load]`in the standard if any overload has a reference specifier (lvalue or rvalue) all have to get one. So The overload for the non-temporary case has to be `const &`. I'm not completely sure wether or not this will bind to a const r-value, so you might need a `const &&` overload to catch that case.

I don't know about the compiler support for this feature, so this might be somewhat theoretical if the support isn't there yet. In that case you might work around by creating a `move_value` method and using a free function which dispatches to the correct method:

template<class T> class wrapper {
    ...    
    T value() const;
    T move_value();    
};
template<typename T> T value(wrapper<T>&& self) { return std::move(self.move_value(); }
template<typename T> T value(const wrapper<T>& self) { return std::move(self.value(); }

Problem

Let's say we have a class that embed another parametric one, that has to support both copy and move. And let's assume that -in certain circumstance- there is the need to get out the inner value somehow. A typical approach can be this one: ``` template<class T> class wrapper { public: wrapper() :val() {} wrapper(T s) :val(std::move(s)) {} wrapper(const wrapper& s) :val(s.val) {} wrapper(wrapper&& s) :val(std::move(s.val)) {} wrapper& operator=(wrapper s) { val = std::move(s.val); return *this; } T value() const { return val; } private: T val; }; ``` That's not the only way of doing it, and may be there is no need to expliciate copy and move, but let them be. The point is another: Suppose `T` -in ceratin instances- is itself a copy/movable class. Of course, `wrapper::value()` returns a copy of T. Now suppose the returned T has to go as a parameter into another call, and that the containing wrapper is temporary. The simpler simulation is ``` calledfn(wrapper<T>(someT).value()); ``` Again: done in this way is clueless, but more complex cases require this trivial one to work. In theory we can admit to move away `val` from its temporary wrapper to give it to the caller, but... what signature should have the `value()` method so that it is bound when `wrapper<T>` is temporary but is not bound when it is not temporary, for which `value() const` should be preferred?

Original source