什么是标准的魔力:移动

Cha*_*ang 5 c++ rvalue-reference c++11

以下代码使VC2010失败:

//code1
std::string& test1(std::string&& x){
  return x;
}
std::string str("xxx");
test1(str);  //#1 You cannot bind an lvalue to an rvalue reference

//code2 
std::string&& test1(std::string&& x){
  return x;  //#2 You cannot bind an lvalue to an rvalue reference
}
Run Code Online (Sandbox Code Playgroud)

有一些文章可以解释#1,但我不明白为什么#2也会失败.

让我们看看std :: move是如何实现的

template<class _Ty> inline
    typename tr1::_Remove_reference<_Ty>::_Type&&
        move(_Ty&& _Arg)
    {   // forward _Arg as movable
    return ((typename tr1::_Remove_reference<_Ty>::_Type&&)_Arg);
    }
Run Code Online (Sandbox Code Playgroud)
  1. move的参数仍然是右值引用,但move(str)是可以的!
  2. move也返回rvalue.

什么是std的魔力:移动?

谢谢

int*_*jay 9

std::move该参数看起来像是一个右值引用,这看起来确实令人困惑 - 为什么你可以调用move(str),何时str不是右值?

这里的技巧是rvalue引用在模板参数上容易混淆:

如果模板参数Tint,T&&则将是右值引用int&&.
但如果T是左值参考int&,那么T&&也将是左值参考int&.

这是因为方式&&&结合:

Type & &&   ==  Type &
Type && &   ==  Type &
Type & &    ==  Type &
Type && &&  ==  Type &&
Run Code Online (Sandbox Code Playgroud)

所以当你调用move(str),Tstd::string&,并且参数类型move<std::string&>也是std::string&- 左值引用,它允许函数调用进行编译.然后,所有move必须做的就是将值转换为右值引用.

  • +1啊,你更好地发现了OP的混乱.`move`的参数类型确实不是右值引用,而是*通用引用*. (2认同)

归档时间:

查看次数:

2190 次

最近记录:

13 年,1 月 前