According to http://en.cppreference.com/w/cpp/utility/move
std::move is declared as follows:
template <typename T> std::remove_reference<T>::type&& move(T&& t); As far as my understanding goes, when code is templated, the deduction of T in typename T looses information about reference, so following:
template <typename T> void someFunction(T&& value); when used like:
int five=5; someFunction(five); then
valueis of typeint&Tisint
or
const float value = 5.25; someFunction(value); then
valueis of typeconst float&Tisconst float.
If this is so, then there is no point in move declaration to declare returned type as: std::remove_reference<T>::type&&, because T is already not a reference.
Moreover, if std::move takes as argument a reference (l-value reference in practice), then returning static_cast<T&&>(t) in std::move in fact due to reference collapsing will return l-value reference or r-value reference, so it will behave more like std::forward not move. So what is a trick, that makes it work properly, that I do not understand?
Tmust beint&ifvalueis to beint&. Reference collapsing. And you don't want that to happen for the return type, you want it to be r-value reference at all times.