std::move的理解

std::move 的定义

template <typename T>
// typename表明type是一个类型
typename remove_reference<T>::type&& move(T&& t)
{
    return static_cast<typename remove_reference<T>::type&&>(t);
}

首先,move函数参数T&&是一个指向模板类型参数的右值引用.通过折叠,此参数可以与任意类型的实参匹配.特别是,我们既可以传递给move一个左值,也可以传递给它一个右值:

string s1("hi"), s2;
s2 = std::move(string("bye!"));  // 正确: 从一个右值移动数据
s2 = std::move(s1);              // 正确: 但是赋值后s1的值不确定

std::move 如何工作

在第一个赋值中,传递给move的实参为string的构造函数的右值结果.当向一个右值引用函数参数传递一个右值时,由实参推断出的类型为被引用的类型.因此,在std::move(string("bye!"))中:

  • 推断出T的类型为string
  • remove_referencestring进行初始化
  • remove_reference<string>type成员是string
  • move的返回类型是string&&
  • move的函数参数t的类型为string&&

因此,这个调用实例化move<string>,即函数

string&& move(string &&t)

函数体返回static_cast<string&&>(t).t的类型已经是string&&,于是类型转化什么都不做.因此,调用的结果就是它所接受的右值引用.

考虑第二个赋值,它调用std::move().此调用中,传递给move的是一个左值.这样:

  • 推断出T的类型为string&
  • remove_referencestring&进行初始化
  • remove_reference<string&>type成员是string
  • move的返回类型是string&&
  • move的函数参数t实例化string& &&,折叠成string&

因此,这个调用实例化move<string&>,即函数

string&& move(string &t)

函数体返回static_cast<string&&>(t).t的类型是string&,cast将其转化为string&&.

posted @ 2021-04-08 00:21  phr2000  阅读(1415)  评论(0编辑  收藏  举报