I got next snippet from microsoft
template <typename T> struct RemoveReference {
typedef T type;
};
template <typename T> struct RemoveReference<T&> {
typedef T type;
};
template <typename T> struct RemoveReference<T&&> {
typedef T type;
};
template <typename T> typename RemoveReference<T>::type&& Move(T&& t) {
return t;
}
…
remote_integer x = frumple(5);
remote_integer&& x1 = Move(x);
and i get an error “error C2440: ‘return’ : cannot convert from ‘remote_integer’ to ‘remote_integer &&'”
something changed in compilers? With std::move all goes right.
The reason your
Movedoesn’t work, is becausetis always lvalue (even whenT&&resolves to, say,int&&). Even though it might seem weird, named rvalue references are indeed lvalues.When returning from your
Move, you attempt to implicitly bind lvalue to rvalue reference, which is forbidden by standard (§8.5.3). As noted in the comments, you have to casttexplicitly to rvalue reference.Relevant parts of standard are §5/4 and §5/5, but I’m going to quote note §5/6, which sums this nicely:
Correct implementation is indeed:
As far as I remember, this code used to be valid in earlier drafts. But since the rules have changed, you have to provide explicit cast now (same applies to std::forward).