C++ 可移动但不可复制的对象:通过值传递还是通过引用传递?

C++ 可移动但不可复制的对象:通过值传递还是通过引用传递?,c++,c++11,parameter-passing,move-semantics,ownership-semantics,C++,C++11,Parameter Passing,Move Semantics,Ownership Semantics,仅考虑可移动但不可复制的对象,例如std::thread或std::unique_ptr,我希望通过将其作为参数传递给构造函数来转移对象所包含的资源的所有权。我比较了两种方法:构造函数通过值获取对象和通过右值引用获取对象 以STD::Type为例,考虑以下构造函数的值:构造函数采用STD::按值线程: 在这种情况下,所有权从参数直接转移到数据成员对象th_ 据我所知,在按值传递的情况下,参数对象和数据成员对象都是move构造的,而对于按引用传递的情况,只有数据成员是move构造的。总之,后一种方

仅考虑可移动但不可复制的对象,例如std::thread或std::unique_ptr,我希望通过将其作为参数传递给构造函数来转移对象所包含的资源的所有权。我比较了两种方法:构造函数通过值获取对象和通过右值引用获取对象

以STD::Type为例,考虑以下构造函数的值:构造函数采用STD::按值线程:

在这种情况下,所有权从参数直接转移到数据成员对象th_

据我所知,在按值传递的情况下,参数对象和数据成员对象都是move构造的,而对于按引用传递的情况,只有数据成员是move构造的。总之,后一种方法似乎更好,因为它只需要一次移动操作,因此效率更高


然而,是否有任何理由更喜欢按值传递方法而不是按引用传递方法?

按值传递是一种自我记录方式,而按引用传递则不是。读者很快就会明白:

构造函数将无条件地拥有由仅移动类型表示的资源的所有权; 如果move构造因任何原因抛出异常而失败,则调用方有责任处理该异常* 如果构造函数通过抛出异常退出,资源将被释放。 同样,在实现过程中很难或不可能出现导致上述假设无法成立的错误

当然,最终的问题是,这些好处是否超过额外搬迁建设的成本,这是一个基于意见的问题


*当然,这不适用于构造函数内部执行的移动,即从参数到成员的移动。但是,这里的要点是,调用方可以控制对象发生的情况:要么将其移动到构造函数参数中,要么在该步骤出现任何故障时,调用方可以进行损坏控制以保留该值。

通过值传递是自文档化,而不是通过引用传递。读者很快就会明白:

构造函数将无条件地拥有由仅移动类型表示的资源的所有权; 如果move构造因任何原因抛出异常而失败,则调用方有责任处理该异常* 如果构造函数通过抛出异常退出,资源将被释放。 同样,在实现过程中很难或不可能出现导致上述假设无法成立的错误

当然,最终的问题是,这些好处是否超过额外搬迁建设的成本,这是一个基于意见的问题

*当然,这不适用于构造函数内部执行的移动,即从参数到成员的移动。但是,这里的要点是调用方可以控制对象发生的情况:要么将其移动到构造函数参数中,要么在该步骤出现任何故障的情况下,调用方可以进行损坏控制以保留该值

#include <thread>
#include <utility>

struct Value {
   Value(std::thread th): th_(std::move(th)) {}
   std::thread th_;
};
struct Reference {
   Reference(std::thread&& th): th_(std::move(th)) {}
   std::thread th_;
};