2017-04-05 85 views
5

我想将一个std::unique_ptr传递给一个类的构造函数,该类将获得std::unique_ptr所拥有的数据的所有权。将std :: unique_ptr传递给构造函数以获得所有权

根据编译器如何处理它们会使其中一个更好?下面的方法foobar之间有什么区别吗?

foo类:

template <class T> 
class foo 
{ 
    std::unique_ptr<T> data_; 

public: 
    foo(std::unique_ptr<T>&& data) : 
     data_{ std::forward<std::unique_ptr<T>>(data) } 
    { 
    } 
}; 

bar类:

template <class T> 
class bar 
{ 
    std::unique_ptr<T> data_; 

public: 
    bar(std::unique_ptr<T> data) : 
     data_{ std::move(data) } 
    { 
    } 
}; 
+0

第二个是否工作? – 101010

+0

如果您的团队对后者不再感到困惑,并且会浪费更少的时间要求您解释它,请使用后者。 –

+0

@KerrekSB做过OP询问团队困惑和浪费时间吗? – Slava

回答

5

绑定到一个参考需要一个更小的举动:

void f(std::unique_ptr<T>&& p) { g(std::move(p)); } 

f(std::make_unique<T>()); // no move, g binds directly to the temporary 

绑定到一个对象参数需要一个实际的举动:

void f(std::unique_ptr<T> p) { g(std::move(p)); } 

f(std::make_unique<T>()); // p constructed (= moved) from temporary, 
          // g binds to p 

额外的移动涉及一个指针副本,一个指向null的指针设置和一个带有条件检查的析构函数。这不是一个大的代价,并且使用哪种样式的问题取决于您正在编写的代码的类型:

代码越多,代码越少,使用的代码越简单价值传递购买你的简单。相反,你的代码越多,你的用户就越少,无论多么小,没有强加可避免成本的价值就越高。

你决定。

+0

在C++ 17中,这个额外的移动将被保证是正确的? – NathanOliver

+2

@NathanOliver:不,这与此无关。这就是为什么我讨厌*“保证副本省略”这个词,它只是让每个人都感到困惑。 –

+0

@NathanOliver:基本上,你应该拒绝所有空白的“X将解决所有Y”的说法,他们都是无稽之谈。 –

相关问题