如何实现移动
- 有分开的拷贝构造和移动构造函数。
- 有swap成员函数,支持和另外一个对象快速交换成员。
- 你的对象的名空间下,应当有一个全局的 swap 函数,调用成员函数 swap 来实现交换。支持这种用法会方便别人(包括你自己在将来)在其他对象里包含你的对象,并快速实现它们的 swap 函数。
- 实现通用的 operator=。
- 上面各个函数如果不抛异常的话,应当标为 noexcept。这对移动构造函数尤为重要。
移动构造函数应当从另一个对象获取资源,清空其资源,并将其 置为一个可析构的状态。
对传递左值和右值都 有效,规避if (&rhs != this) 这样的判断小技巧:
smart_ptr& operator=(smart_ptr rhs) noexcept { rhs.swap(*this); return *this; }
(初始化参数rhs的时候,根据传入的是左值还是右值去匹配初始化)
不要返回本地变量的引用(C++11开始)
从 C++11 开始,返回值优化仍可以发生,但在没有返回值优化的情况下,编译器将 试图把本地对象移动出去,而不是拷贝出去。这一行为不需要程序员手工用 std::move 进 行干预——使用std::move 对于移动行为没有帮助,反而会影响返回值优化。
引用坍缩和完美转发
对于 template foo(T&&) 这样的代码,如果传递过去的参数是左值,T的推导结果是左值引用;如果传递过去的参数是右值,T 的推导结果是参数的类型本身(右值引用变量仍然会匹配到左值引用上)。
如果 T 是左值引用,那 T&& 的结果仍然是左值引用——即 type& && 坍缩成了 type&。 如果 T 是一个实际类型,那 T&& 的结果自然就是一个右值引用。
应对策略:std::forward
template <typename T> void bar(T&& s) { foo(std::forward<T>(s)); }
因为在 T 是模板参数时,T&& 的作用主要是保持值类别进行转发,它有个名字就叫“转发 引用”(forwarding reference)。因为既可以是左值引用,也可以是右值引用,它也曾 经被叫做“万能引用”(universal reference)。
标签:右值,左值,C++,引用,&&,移动,swap From: https://www.cnblogs.com/JohnsonQ/p/17017974.html