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_reference
用string
进行初始化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_reference
用string&
进行初始化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&&
.