template <class T>swap(T& a, T& b) {T tmp(a); // we now have two copies of aa = b; // we now have two copies of b (+ discarded a copy of a)b = tmp; // we now have two copies of tmp (+ discarded a copy of b)}
使用移动允许您交换资源,而不是到处复制它们:
template <class T>swap(T& a, T& b) {T tmp(std::move(a));a = std::move(b);b = std::move(tmp);}
foo(3 * 5); // obviously, you are calling foo with a temporary (rvalue)
int a = 3 * 5;foo(a); // how to tell the compiler to treat `a` as an rvalue?foo(std::move(a)); // will call `foo(int&& a)` rather than `foo(int a)` or `foo(int& a)`
class ResHeavy{ // ResHeavy means heavy resourcepublic:ResHeavy(int len=10):_upInt(new int[len]),_len(len){cout<<"default ctor"<<endl;}
ResHeavy(const ResHeavy& rhs):_upInt(new int[rhs._len]),_len(rhs._len){cout<<"copy ctor"<<endl;}
ResHeavy& operator=(const ResHeavy& rhs){_upInt.reset(new int[rhs._len]);_len = rhs._len;cout<<"operator= ctor"<<endl;}
ResHeavy(ResHeavy&& rhs){_upInt = std::move(rhs._upInt);_len = rhs._len;rhs._len = 0;cout<<"move ctor"<<endl;}
// check array validbool is_up_valid(){return _upInt != nullptr;}
private:std::unique_ptr<int[]> _upInt; // heavy array resourceint _len; // length of int array};
测试代码:
void test_std_move2(){ResHeavy rh; // only one int[]// operator rh
// after some operator of rh, it becomes no-use// transform it to other objectResHeavy rh2 = std::move(rh); // rh becomes invalid
// show rh, rh2 it validif(rh.is_up_valid())cout<<"rh valid"<<endl;elsecout<<"rh invalid"<<endl;
if(rh2.is_up_valid())cout<<"rh2 valid"<<endl;elsecout<<"rh2 invalid"<<endl;
// new ResHeavy object, created by copy ctorResHeavy rh3(rh2); // two copy of int[]
if(rh3.is_up_valid())cout<<"rh3 valid"<<endl;elsecout<<"rh3 invalid"<<endl;}