4

Here is a possible implementation of std::move(). It's not fully conforming to the details of the standard, but it's very close:

template<class T>
typename std::remove_reference<T>::type&&
myMove( T&& Arg )
{   
    return ( ( typename std::remove_reference<T>::type&& )Arg );
}

I don't understand why it wouldn't work if we replace typename std::remove_reference<T>::type&& by the T&&, i.e.

template<class T>
typename std::remove_reference<T>::type&&
myMove( T&& Arg )
{   
    return ( (T&&) Arg );
}
bolov
  • 72,283
  • 15
  • 145
  • 224
David
  • 157
  • 1
  • 8

1 Answers1

6

The issue is not really about the move, but the reference collapsing that happens with T&&.

The are nice write-ups about this here and these Q&A here, and here.

I'll focus on the cast (T&&) and why that doesn't work.

Given the reference collapsing rules listed above;

  • T& & becomes T&
  • T& && becomes T&
  • T&& & becomes T&
  • T&& && becomes T&&

The problem arises when T is deduced to be an lvalue reference, then T&& becomes T& && which collapses to T&, given the cast, you merely cast it back to an lvalue reference and you have not gained the rvalue reference that enables moving to happen.

The std::remove_reference<T>::type is there to remove all the references and the && then adds back the rvalue ref and thus ensures the correct cast is made.

The typename is there to disambiguate the member type over a member variable.

Community
  • 1
  • 1
Niall
  • 30,036
  • 10
  • 99
  • 142