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

C++11 copying std::vector of std::unique_ptr which is a member

我有一个 class 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,那么我将违反参数 rhsconstness,这不是我想要的。 我知道我可以进行深层复制(例如,为存储在 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)));
}

你不能制作副本,但你可以制作移动构造函数:

graph::graph(graph && rhs)

您应该能够在其中移动 _layers 向量,然后您应该能够移动 graph 个实例。

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

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

最优雅的解决方案是使用 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::transform, std::back_inserter

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