std::move的定义如下:
1 template <typename T> 2 typename remove_reference<T>::type && move(T&& t) 3 { 4 return static_cast<typename remove_reference<T>::type&&>(t); 5 }
通过引用折叠,此参数可以与任何类型的实参匹配,既可以传递给move一个左值引用也可以传右值引用,如:
string s1("hi"), s2;
s2 = std::move(string("bye1!"));//正确,从一个右值移动数据
s2 = std::move(s1);//正确,但赋值之后,s1的值是不确定的。
1)针对std::move(string("bye1!")); 传入的已经是右值引用
- 函数模板推断出T的类型为string
- 因此,remove_reference用string进行实例化
- remove_reference<string>的 type成员是string
- move的返回类型是string&&move的函数参数t的类型是string&&
string&& move(string&& t);
函数体返回static_cast<string&&>(t),由于t的类型已经是右值引用,因此无需进行任何转化。
2)针对std::move(s1); 传入的就是一个左值
- 函数模板推断出T的类型是string&(因为string& &&才能折叠为string&)
- 因此,remove_reference用string&进行实例化
- remove_reference<string>的 type成员是string
- move的返回类型是string&&
- move的函数参数t的类型是string& &&,会折叠为string&
因此等价于:
string&& move(string& t);
函数体返回static_cast<string&&>(t),这里t的类型是string&,通过static_cast将其转化为string&&