如何将向量<unique_ptr<T>> 复制到独立向量<T*>

How to copy vector<unique_ptr<T>> to independent vector<T*>

我有一个 std::vector<std::unique_ptr<T>> vec1,其中 T 是一个抽象类型。我想创建 std::vector<T*> vec2,其中第二个向量的指针指向的对象是第一个向量的指针指向的对象的副本。

例如:*(vec1[0]) == *(vec2[0])vec1[0].get() != vec2[0] ... 等等...

怎么做?

手动方式:

std::vector<std::unique_ptr<T>> vec1;
std::vector<T*> vec2;
vec2.reserve(vec1.size()); // optimization to avoid reallocations

for (const auto& e : vec1) {
    vec2.push_back(e->clone());
}

virtual T* T::clone() const

使用std::transform

std::vector<T*> vec2;
vec2.reserve(vec1.size()); // optimization to avoid reallocations, it isn't necessary, and without it the code still works correctly
std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2), [](const std::unique_ptr<T>& p){ return YourCloneFunction(*p); }

编写克隆函数的一种方法是让您的所有后代 class 都定义了虚拟 clone 函数,它在 T 中是抽象的。这种方法的代码很简单,但是需要为每个 Derived class.

定义
class T
{
    virtual std::unique_ptr<T> clone() const = 0;
    virtual ~T(){}
};

class Derived : public T
{
    std::unique_ptr<T> clone() const override {
        return std::unique_ptr<T>(new Derived(*this));
    }
};

有了这个,代码就变成了

std::vector<T*> vec2;
vec2.reserve(vec1.size()); // optimization to avoid reallocations, it isn't necessary, and without it the code still works correctly
std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2), [](const std::unique_ptr<T>& p){ return p->clone().release(); }

请注意,我们有 vec2 个指向不属于任何智能指针的对象的原始指针。这很糟糕,除非您将 vec2 传递给拥有这些指针所有权的遗留函数。

否则,如果您只需要副本的 std::vector<T*> 视图,请克隆到中间 std::vector<std::unique_ptr<T>>,然后将每个实例上 .get() 的结果复制到 std::vector<T*>