std::move与std::forward
在老版C++中,临时变量(称为右值”R-values”)经常用作交换两个变量。比如下面例子中的tmp变量,这个函数需要传递两个string引用,但在交换的过程中需要一个临时的对象tmp,这样就造成了对象的构造,内存的分配还有对象的拷贝构造等动作,成本比较高。1
2
3
4
5void Swap(string &a, string &b) {
string tmp = a;
a = b;
b = tmp;
}
C++ 11增加了一个新的引用类型–右值引用,通过typename &&来定义。他们能够以non-const值的方式传入,允许对象去修改他们。
在上面的例子中,string保存了一个动态内存分配的char指针,如果一个string对象发生拷贝构造,只能构造一个新的临时对象,并把源对象的内存拷贝到新的对象里,然后销毁临时对象及其内存。这样会造成性能的问题。
通过右值引用,string的构造函数需要改成”move构造函数”,如下所示。这样的话,对某个string的右值引用就可以单纯的从右值复制其内部的char指针到新的string,然后留下空的右值。这个操作不需要内存数组的复制,而且空的暂时对象的析构并不会释放内存,这样就提高了效率。1
2
3
4class string {
string (string&&);
string&& operator = (string&&);
};
std::move
定义在头文件1
2template< typename T >
typename std::remove_reference<T>::type&& move( T&& t ) noexcept ; //(C++11 - C++14)
1 | template< typename T > |
std::move返回指向实参的右值引用,并将实参转化为将亡值(xvalue, eXpiring Value)。
std::forward转发
定义在头文件1
2template< typename T >
T&& forward( typename std::remove_reference<T>::type& t ) noexcept ; //(1) (C++11 - C++14)
1 | template< typename T > |
1 | template< typename T > |
1 | template< typename T > |
TODO