1. std::move
它唯一的功能是将一个左值/右值强制转化为右值引用
,继而可以通过右值引用使用该值,所以称为移动语义
。
std::move的作用:将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝所以可以提高利用效率,改善性能。
/**
* @brief Convert a value to an rvalue.
* @param __t A thing of arbitrary type.
* @return The parameter cast to an rvalue-reference to allow moving it.
*/
template <typename T>
typename remove_reference<T>::type&& move(T&& t)
{
return static_cast<typename remove_reference<T>::type&&>(t);
}
std::move的常用例子
1 用于vector添加值
#include <iostream>
#include <utility>
#include <vector>
#include <string>
int main()
{
std::string str = "Hello";
std::vector<std::string> v;
//调用常规的拷贝构造函数,新建字符数组,拷贝数据
v.push_back(str);
std::cout << "After copy, str is \"" << str << "\"\n";
//调用移动构造函数,掏空str,掏空后,最好不要使用str
v.push_back(std::move(str));
std::cout << "After move, str is \"" << str << "\"\n";
std::cout << "The contents of the vector are \"" << v[0]
<< "\", \"" << v[1] << "\"\n";
}
输出:
After copy, str is "Hello"
After move, str is ""
The contents of the vector are "Hello", "Hello"
2. std::foward
完美转发(perfect forwarding)问题是指函数模板在向其他函数传递参数时该如何保留该参数的左右值属性的问题。
也就是说函数模板在向其他函数传递自身形参时,如果相应实参是左值,它就应该被转发为左值;同样如果相应实参是右值,它就应该被转发为右值。
这样做是为了保留在其他函数针对转发而来的参数的左右值属性进行不同处理(比如参数为左值时实施拷贝语义;参数为右值时实施移动语义)的可能性。
如果将自身参数不分左右值一律转发为左值,其他函数就只能将转发而来的参数视为左值,从而失去针对该参数的左右值属性进行不同处理的可能性。
#include "stdafx.h"
#include <iostream>
using namespace std;
void fun(int &x) { cout << "lvalue ref" << endl; }
void fun(int &&x) { cout << "rvalue ref" << endl; }
void fun(const int &x) { cout << "const lvalue ref" << endl; }
void fun(const int &&x) { cout << "const rvalue ref" << endl; }
template<typename T>
void PerfectForward(T &&t) { fun(std::forward<T>(t)); }
int _tmain(int argc, _TCHAR* argv[])
{
PerfectForward(10); // rvalue ref
int a;
PerfectForward(a); // lvalue ref
PerfectForward(std::move(a)); // rvalue ref
const int b = 8;
PerfectForward(b); // const lvalue ref
PerfectForward(std::move(b)); // const rvalue ref
system("pause");
return 0;
}