Reputation:
Following is the code snippet:
int i=0;
int&&k=std::move(i);
In c++ primer the move is
template <typename T>
typename remove_reference<T>::type &&move(T&& t)
{return static_cast<typename remove_reference<T>::type&&>(t);}
As far as i know,this std::move
template will deduct a function like
int&& move(int& t){return static_cast<int&&>(t);}
As a comparison and to elaborate my question,consider an example like this:
int test(int k){k=66;return k;}
int k;
int a=test(k);
The code above will be compiled as:
int temp;//the temporary object
temp=k;
int a=temp;
Similarly,i think the first code snippet will be compiled as:
int&& temp=0;
int&& k=temp;//oop!temp is an lvalue!
which seems wrong because temp
is an lvalue,did i get something wrong?
Upvotes: 6
Views: 414
Reputation: 172934
Similarly,i think the first code snippet will be compiled as:
int&& temp=0; int&& k=temp;//oop!temp is an lvalue!
You might be confusing type with value category.
Each C++ expression (an operator with its operands, a literal, a variable name, etc.) is characterized by two independent properties: a type and a value category.
int&&k=std::move(i);
and int&& k=temp;
are not identical. The return type of std::move
is rvalue-reference and then what std::move
returns is an rvalue (more precisely it's an xvalue), which could be bound to rvalue-reference. On the other hand temp
is a named variable then it's always an lvalue, regardless of whether its type is int
, int&
, int&&
etc. Lvalue can't be bound to rvalue-reference.
More infomations about lvalue:
The following expressions are lvalue expressions:
- the name of a variable, ...
and xvalue(rvalue):
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)
;- ...
- a cast expression to rvalue reference to object type, such as
static_cast<char&&>(x)
;
Upvotes: 4