2016-01-11 106 views
0

我有一个类其具有构件:C++ 11复制的std ::的std ::的unique_ptr的载体,其为一个构件

std::vector<std::unique_ptr<layer>> _layers; 

我明白的std::unique_ptr性质是成非可复制。 我的graph::graph(const graph & rhs);拷贝构造函数产生一个编译错误,因为我的普通实现违反了std::unique_ptr的性质。

graph::graph(const graph & rhs) 
: _layers(rhs._layers) {} 

如果我做了std::move那么我会违反PARAM rhs常量性,这不是我想要的。 我知道我可以制作深层副本(例如,为存储在rhs._layers中的每个对象创建新的唯一指针),但是有没有一些优雅的方式来执行此操作,除了迭代每个项目并分配新的唯一指针?

GCC/G ++是C++ 11不是C++ 14

我目前的解决方案是深拷贝的对象和分配新指针:

graph::graph(const graph & rhs) 
{ 
    for (const auto & ptr : rhs._layers) 
     _layers.emplace_back(std::unique_ptr<layer>(new layer(*ptr))); 
} 
+0

这已经在这里讨论过了:http://stackoverflow.com/questions/16030081/copy-constr uctor-for-a-class-with-unique-ptr –

+0

未受教育的猜测:对于'shared_ptr's视图的'weak_ptr',这会是一个很好的用例吗? – Katana314

+0

@ Katana314我不知道TBH,但这些指针不能在课堂以外看到或访问。我不介意复制对象(因此深层复制)。这种情况下'weak_ptr'的优点是什么? –

回答

2

最优雅的解决方案将使用STL:

graph::graph(const graph & rhs) 
{ 
    _layers.reserve(rhs._layers.size()); 
    std::transform(
     std::begin(rhs._layers) 
     , std::end(rhs._layers) 
     , std::back_inserter(_layers) 
     , [](const std::unique_ptr<layer>& up) { 
      return std::unique_ptr<layer>{up ? (new layer{*up}) : nullptr}; 
     }); 
} 

std::transformstd::back_inserterstd::make_unique

+0

没有C++ 14,这和我已经做的一样。我想我需要模板专门化为我的类型。 –

+0

@Alex STL应该优先于原始循环,但是这是相同的。用C++ 11友好版本更新。 –

0

你不能让一个副本,但你可以使移动构造函数:

graph::graph(graph && rhs) 

你应该能够移动_layers向量在那里,那么你应该能够移动实例。

如果这不是你想要的,那么你将不得不放弃使用unique_ptr或向_layers向量添加一个间接层,如果这可以在图实例之间共享。

编辑:另一种解决方案是根本不使用向量中的指针,而是直接将实例放入向量中。这样,矢量将自然地与所有内容一起被复制。

+0

这违反了const对象参数的全部观点。此外,我不感兴趣*移动*,但*复制*。 –

+0

@Alex那么你首先不应该使用'std :: unique_ptr'。你有没有理由在这里使用指针?你可以在矢量中放置实例吗? – Fozi

1

您还可以查看可能使用的std :: shared_ptr的矢量STD代替的:: unique,在这种情况下你可以避免真正的复制

+0

shared_ptr意味着其他人可以修改对象,不是吗? –

+0

@Alex不是,如果它们是:'std :: shared_ptr '。我同意这很可能是你正在寻找的行为 –

相关问题