std::unique_ptr 作为参数的正确复制语义

Posted

技术标签:

【中文标题】std::unique_ptr 作为参数的正确复制语义【英文标题】:Proper copy semantics for std::unique_ptr as a parameter 【发布时间】:2011-12-03 07:00:48 【问题描述】:

是否对接口进行了修改,可以使第二次调用生效?

或者我应该保持原样?

我怀疑第一种情况下的额外结构是故意这样设计的,因此很明显所有权正在转移。

#include <memory>

struct Bar  ;
typedef std::unique_ptr<Bar> UPBar;

void foo1( UPBar p )   
void foo2( UPBar p )  foo1( move( p )); 
void foo3( UPBar p )  foo2( move( p )); 
void foo4( UPBar p )  foo3( move( p )); 

int main(int argc, char** argv)

    UPBar p( new Bar );
    foo4( move( p ));  // ok, but requires an extra construction vs line below
    foo4( new Bar );   // fails: any modification to get this to work?

    return 0;

第二个问题:如果我更改所有传递给 RValue-References (&&) 的参数,这样做有什么缺点吗?事实上,我是否应该确保我所有的std::unique_ptr&lt;&gt; 参数都由 RValue-References 传递?

【问题讨论】:

【参考方案1】:

您可以将unique_ptr 构造为临时:

foo4( UPBar( new Bar ));

您还可以编写一个make_unique 函数模板,类似于为shared_ptr 存在的make_shared

template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) 
    return std::unique_ptr<T>(new T(std::forward<T>(args)...));


foo4( make_unique<Bar>() );
// other constructors are also callable:
foo4( make_unique<Bar>(x, y, z) );

【讨论】:

效果很好 - tyvm。优秀的第二个提示 - ty。顺便说一句,我应该将所有 fooX() 函数更改为接受 RHR/&& 而不是按值传递吗? @kfmfe04:没有。始终按价值取 unique_ptrs。看到这个问题:***.com/questions/8114276/…。我在这个函数中使用&amp;&amp; 的参数,因为它们将被转发给构造函数。

以上是关于std::unique_ptr 作为参数的正确复制语义的主要内容,如果未能解决你的问题,请参考以下文章

如何创建一个可以将 std::unique_ptr 作为模板参数正常工作的容器?

复制接口的 std::unique_ptr [关闭]

vector<unique_ptr> 的初始化失败并出现复制错误

提升::变体; std::unique_ptr 和复制

通过 std::unique_ptr 的 LazyArray 模板,这是双重检查习语的正确实现吗?

模板类重载 std::bind 成员函数