0

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

  • value is of type int&
  • T is int

or

const float value = 5.25; someFunction(value); 

then

  • value is of type const float&
  • T is const 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?

2
  • 1
    T must be int& if value is to be int&. 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. Commented Feb 8, 2016 at 9:51
  • I once made this very same mistake. How embarrassing! :-) open-std.org/jtc1/sc22/wg21/docs/papers/2002/… Commented Feb 8, 2016 at 15:18

1 Answer 1

8

Your examples are incorrect:

int five=5; someFunction(five); 

In this case, T is deduced as int&, not int. The same goes for the second example; T is deduced as const int&.

As such, returning just T&& would mean T&& &, which is T& due to reference collapsing rules.

This is why the std::remove_reference is required, to ensure that there are no references on the type to prevent reference collapsing from taking place.

Sign up to request clarification or add additional context in comments.

6 Comments

what would be T then, if I had a function following: template <typename T> void function(T& a, T&& b); ?
@DawidPi and pass what to it?
yeah right sorry, int a, b, function(a,std::move(b));
T is int in that case.
@DawidPi Template deduction rules are pretty complicated. Essentially, references are usually not deduced for T, but there's a special case for T&& parameters which states that A& is used instead of A if the argument is an lvalue (where A is the type of the argument).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.