[英]shared_ptr from unique_ptr of abstract class
我试图遵循Herb Sutter的C ++指南,在这种情况下更喜欢unique_ptr
到原始指针和shared_ptr
。 支持std::unique_ptr
一个参数是在某些时候需要转换为shared_ptr
。
在我的例子中,我有一个unique_ptr
的vector
,我需要传递给一个带有shared_ptr
vector
的方法。 我希望能写出类似的东西:
for (auto &uniquePtr : vectorUnique)
vectorShared.push_back(make_shared<Abstract>(move(uniquePtr));
这为我为基于Xcode 7.1
的C++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.