使用和不使用移动从 unique_ptr 构造 shared_ptr?

Posted

技术标签:

【中文标题】使用和不使用移动从 unique_ptr 构造 shared_ptr?【英文标题】:Constructing shared_ptr from unique_ptr with and without move? 【发布时间】:2021-06-01 14:29:36 【问题描述】:

我在这里看到了高度赞成的答案 (https://***.com/a/37885232/3754760),有两种方法可以将 unique_ptr 转换为 shared_ptr,即首先创建 unique_ptr,然后将其 move-ing 到 shared_ptr,以及将 unique_ptr 直接分配给 shared_ptr。

例子:

std::unique_ptr<std::string> unique = std::make_unique<std::string>("test");
std::shared_ptr<std::string> shared = std::move(unique);

或:

std::shared_ptr<std::string> shared = std::make_unique<std::string>("test");

以上两者在性能方面是否等效?其次,当我做这样的事情时,我会看到类似Moving a temporary object prevents copy elision 的警告:

std::shared_ptr<std::string> shared = std::move(std::make_unique<std::string>("test"));

作为一个对智能指针很陌生的人,有人能解释一下这个警告的含义以及它为什么会出现在第三个例子中吗?谢谢!

【问题讨论】:

【参考方案1】:

以上两个是等价的吗

是的

有人能解释一下这个警告是什么意思吗?为什么它会出现在第三个例子中?

Copy Elison 仅在返回临时对象的函数调用的结果直接分配给变量时才有效。编译器可以优化掉临时对象,让函数直接初始化变量。但是在第三个示例中,在构建临时对象和将临时对象分配给变量之间执行了中间类型转换,因此无法优化临时对象。

【讨论】:

我要补充一点,std::make_unique 已经返回了一个临时对象(右值),所以 std::move 在逻辑上是错误的(并且会误导将在几周内使用此代码的开发人员,可能永远是你)

以上是关于使用和不使用移动从 unique_ptr 构造 shared_ptr?的主要内容,如果未能解决你的问题,请参考以下文章

Pimpl with unique_ptr:为什么我必须将接口构造函数的定义移动到“.cpp”?

从函数返回 unique_ptr

从函数返回 unique_ptr

std::将 std::unique_ptr 移动到 stl 容器中。 (MSVC 编译器问题)

为啥 unique_ptr<T> 不能从 T* 构造?

在构造函数中使用 unique_ptr