为什么std :: move()在c ++中工作?

时间:2018-02-22 14:57:47

标签: c++ c++11 stdmove value-categories

以下是代码段:

int i=0;
int&&k=std::move(i);

在c ++入门中,此举是

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

据我所知,此std::move模板会扣除类似

的功能
int&& move(int& t){return static_cast<int&&>(t);}

作为比较并详细说明我的问题,请考虑以下示例:

 int test(int k){k=66;return k;}
 int k;
 int a=test(k);

上面的代码将编译为:

int temp;//the temporary object
temp=k;
int a=temp;

同样,我认为第一个代码片段将被编译为:

int&& temp=0;
int&& k=temp;//oop!temp is an lvalue!

这似乎不对,因为temp是一个左值,我出错了吗?

1 个答案:

答案 0 :(得分:4)

  

同样,我认为第一个代码片段将被编译为:

int&& temp=0;
int&& k=temp;//oop!temp is an lvalue!

您可能会将类型value category混淆。

  

每个C ++表达式(具有操作数,文字,变量名等的运算符)由两个独立属性表征:类型值类别

int&&k=std::move(i);int&& k=temp;不相同。 std::move的返回类型是rvalue-reference,然后std::move返回的是rvalue(更准确地说是xvalue),它可以绑定到rvalue-reference。另一方面,temp是一个命名变量,然后它总是一个左值,无论其类型是intint&int&&等等。左值都不能被绑定到rvalue-reference。

有关lvalue的更多信息:

  

以下表达式是左值表达式:

     
      
  • 变量的名称,......
  •   

xvalue(rvalue)

  

以下表达式是xvalue表达式:

     
      
  • 函数调用或重载的运算符表达式,其返回类型是对象的右值引用,例如std::move(x);
  •   
  • ...
  •   
  • 将表达式转换为对对象类型的右值引用,例如static_cast<char&&>(x);
  •