繁体   English   中英

来自抽象类的unique_ptr的shared_ptr

[英]shared_ptr from unique_ptr of abstract class

我试图遵循Herb Sutter的C ++指南,在这种情况下更喜欢unique_ptr到原始指针和shared_ptr 支持std::unique_ptr一个参数是在某些时候需要转换为shared_ptr

在我的例子中,我有一个unique_ptrvector ,我需要传递给一个带有shared_ptr vector的方法。 我希望能写出类似的东西:

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

这为我为基于Xcode 7.1C++11工具链配置了以下错误:

错误:字段类型'Abstract'是一个抽象类。

当我使用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()的调用,则可以将其推广到更多容器。

我会这样做:

for (auto &uniquePtr : vectorUnique) {
    vectorShared.emplace_back(std::move(uniquePtr));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM