gpt4 book ai didi

c++ - 来自抽象类的 unique_ptr 的 shared_ptr

转载 作者:太空狗 更新时间:2023-10-29 23:44:13 26 4
gpt4 key购买 nike

我正在尝试遵循 Herb Sutter 的 C++ 指南,在这种情况下,我更喜欢 unique_ptr 而不是原始指针和 shared_ptr。支持 std::unique_ptr 的论点之一是在某些时候需要时可以转换为 shared_ptr

在我的例子中,我有一个 vectorunique_ptr 我需要传递给一个方法,该方法采用 shared_ptr 的 vector 。我希望能够写出类似这样的东西:

for (auto &uniquePtr : vectorUnique)
vectorShared.push_back(make_shared<Abstract>(move(uniquePtr));

这为我的 Xcode 7.1 配置了 C++11 的工具链带来了以下错误:

error: field type 'Abstract' is an abstract class.

当我使用 make_shared 时,STL 似乎试图保存类型为 Abstract 的具体实例。在许多情况下,这似乎会使 Sutter 先生的建议行不通,所以我确定我一定做错了什么!我求助于写作:

for (auto &uniquePtr : vectorUnique) {
auto ptr = uniquePtr.get();
auto shared = shared_ptr<Abstract>(ptr);
vectorShared.push_back(shared);
uniquePtr.release();
}

有更好的方法吗?

最佳答案

make_shared使用给定的参数构造一个新对象并返回一个 shared_ptr给它。所以编译器需要一个构造函数 Abstract(std::unique_ptr<Abstract>) ,这可能不是您拥有的。

你想要的是shared_ptr的构造函数这需要 unique_ptr参数:

    vectorShared.push_back(shared_ptr<Abstract>(move(uniquePtr)));

而且,因为它不是 explicit , 然后

    vectorShared.emplace_back(move(uniquePtr));

将正常工作(根据 Richard Hodges 的建议,我使用 emplace_back 来避免冗余复制)。甚至还有一个标准算法,因此您不需要 for循环:

    std::move(vectorUnique.begin(), vectorUnique.end(),
std::back_inserter(vectorShared));

如果你经常需要这个,你可以定义一个函数:

#include <vector>
#include <memory>
#include <algorithm>

template<typename T>
std::vector<std::shared_ptr<T>>
convert_to_shared(std::vector<std::unique_ptr<T>>&& vu)
{
using std::begin;
using std::end;
std::vector<std::shared_ptr<T>> vs;
vs.reserve(vu.size());
std::move(begin(vu), end(vu), std::back_inserter(vs));
return vs;
}


// Example of use
class Abstract {};
int main()
{
std::vector<std::unique_ptr<Abstract>> vectorUnique;
std::vector<std::shared_ptr<Abstract>> vectorShared
= convert_to_shared(std::move(vectorUnique));
}

抱歉这个糟糕的名字(我愿意接受建议)。如果您省略对 reserve() 的调用,您可以将其推广到更多容器。

关于c++ - 来自抽象类的 unique_ptr 的 shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34163186/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com