C ++ 11复制作为成员的std :: unique_ptr的std :: vector

时间:2016-01-11 16:26:54

标签: c++11 vector copy-constructor unique-ptr

我有一个班级graph,其中有一个成员:

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 constness ,这不是我想要的。 我知道我可以制作深层副本(例如,为rhs._layers中存储的每个对象创建新的唯一指针)但除了迭代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)));
}

3 个答案:

答案 0 :(得分:5)

最优雅的解决方案是使用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>& uptr) {
            return std::unique_ptr<layer>{uptr ? new layer{*uptr} : nullptr};
        });
}

std::transformstd::back_inserter

答案 1 :(得分:1)

您还可以查看使用std :: shared_ptr的向量而不是std :: unique的可能性,在这种情况下,您可以避免真正的复制

答案 2 :(得分:0)

您无法制作副本但您可以制作移动构造函数:

graph::graph(graph && rhs)

您应该可以在那里移动_layers向量,然后您就可以移动graph个实例。

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

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