我有一个std::vector<std::unique_ptr<T>> vec1
,其中T是抽象类型。我想创建std::vector<T*> vec2
,其中第二个向量指针指向的对象是第一个向量指针指向的对象的副本。
例如:*(vec1[0]) == *(vec2[0])
和vec1[0].get() != vec2[0]
......等......
怎么做?
答案 0 :(得分:5)
使用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); }
编写克隆函数的一种方法是使所有后代类都定义了虚拟clone
函数,这在T
中是抽象的。这种方法的代码很简单,但需要为每个Derived
类定义。
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*>
答案 1 :(得分: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