std::move
1. std::move代码原型:
template <typename T> typename remove_reference<T>::type&& move(T&& t) { return static_cast<typename remove_reference<T>::type &&>(t); }
std::forward完美转发
1. std::forward代码原型:
template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept { return static_cast<T&&>(t); } template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept { return static_cast<T&&>(t); }
2. 分析std::forward<T>实现条件转发的原理(以转发Widget类对象为例)
- 当传递给func函数的实参类型为左值Widget时,T被推导为Widget&,然后forward会实例化为std::forward<Widget&>,并返回Widget&(左值引用,根据定义是个左值!)
- 而当传递给func函数的实参类型为右值Widget时,T被推导为Widget。然后forward被实例化为std::forward<Widget>,并返回Widget&&(注意,匿名的右值引用是个右值!)
- 可见,std::forward会根据传递给func函数实参(注意,不是形参)的左/右值类型进行转发。当传给func函数左值实参时,forward返回左值引用,并将该左值转发给process。而当传入func的实参为右值时,forward返回右值引用,并将该右值转发给process函数。
1. 示例
1 #include <iostream> 2 using namespace std; 3 4 template <typename Tp> 5 inline typename std::remove_reference<_Tp>::type &&my_move(Tp &&t) 6 { 7 cout << &t << endl; 8 return static_cast<typename std::remove_reference<Tp>::type &&>(t); 9 } 10 11 template <typename Tp> 12 inline Tp &&my_forward(typename std::remove_reference<Tp>::type &t) 13 { 14 cout << "calling lvalue forward" << endl; 15 return static_cast<Tp &&>(t); 16 } 17 18 template <typename Tp> 19 inline Tp &&my_forward(typename std::remove_reference<Tp>::type &&t) 20 { 21 cout << "calling rvalue forward" << endl; 22 static_assert(!std::is_lvalue_reference<_Tp>::value, 23 "template argument substituting Tp is an lvalue reference type"); 24 return static_cast<Tp &&>(t); 25 } 26 27 struct X 28 { 29 }; 30 31 void inner(const X &) { cout << "inner(const X&)" << endl; } 32 void inner(X &&) { cout << "inner(X&&)" << endl; } 33 template <typename T> 34 void outer(T &&t) 35 { 36 inner(my_forward<T>(t)); 37 } 38 39 int main() 40 { 41 cout << ">>> test move" << endl; 42 X a1; 43 cout << &a1 << endl; 44 cout << "> test lvalue" << endl; 45 X &&b = my_move(a1); 46 cout << "> test rvalue" << endl; 47 X &&c = my_move(X()); 48 49 cout << endl; 50 51 cout << ">>> test forward" << endl; 52 X a2; 53 cout << "> test lvalue indirectly" << endl; 54 outer(a2); 55 cout << "> test rvalue indirectly" << endl; 56 outer(X()); 57 cout << "> test rvalue directly" << endl; 58 inner(my_forward<X>(X())); 59 }