Home > Blockchain >  std::move explained through an example
std::move explained through an example

Time:12-09

I am trying to understand how std::move works and I bumped into some problems: so, this is the implementation:

template <typename T>
typename remove_reference<T>::type&& move(T&& t){
     return static_cast<typename remove_reference::type&&>(t);

Let me go through this snippet line by line by using

string s2;
s2 = std::move(string("hello"));
  1. the constructor for the string hello is going to return an rvalue.
  2. type deduction rules tell us that if I am passing an rvalue to a parameter&& I get the referred type hence string in this case.
  3. Now comes the static_cast part
  4. remove_reference<T> is going to be simply remove_reference<string> which is simply string
  5. What I don’t get is this type&& thing. I have seen already something like ::type but I don’t know if ::type&& makes a difference.
  6. So I am converting t whose type has been deduced to string (here could be my misunderstanding) to all this thing which seems to be just string. I know that std::move needs to return an rvalue reference no matter if we pass an rvalue or an lvalue to it, i simply cannot get there. Could someone help?

CodePudding user response:

remove_reference<string> is NOT the same as just string. It is a struct that has a typedef type in its scope that is defined to string. So remove_reference<string>::type is string.

Thus remove_reference<string>::type&& is string&& which is an rvalue reference to string

A shorter way to write that would be remove_reference_t<string>&& (notice the _t)

CodePudding user response:

1 ~ 3 are correct. From 4,

remove_reference<string> is ..., remove_reference<string>, it's not string. remove_reference<string>::type is string. So remove_reference<string>::type&& is string&&, i.e. an rvalue-reference to string. Since the return type of std::move is rvalue-reference, std::move(...) leads to an xvalue:

The following expressions are xvalue expressions:

  • a function call or an overloaded operator expression, whose return type is rvalue reference to object, such as std::move(x);
  • ...

As the effect, std::move(string("hello")) is converting an prvalue string("hello") to xvalue, even both prvalue and xvalue are rvalues. std::move is supposed to be used to convert lvalue to rvalue, so the usage like this doesn't make much sense.

CodePudding user response:

It's not strictly relevant to the question, but good to know.
The type of t as a template parameter looks like a rvalue-reference, but may not be

template <typename T>
RetType fn(T&& t)

It's a special case, that says : "Use T&& or constT& as required"

See here for a better explanation than I could ever give

Edit: Actually, you need to know this to answer part 6 of your question.

  •  Tags:  
  • c
  • Related