Reputation: 1475
I have a std::vector<std::unique_ptr<T>> vec1
where T is an abstract type. I'd like to create std::vector<T*> vec2
where objects pointed by pointers from 2nd vector are copy of objects pointed by pointers of 1st vector.
So for example: *(vec1[0]) == *(vec2[0])
and vec1[0].get() != vec2[0]
... etc...
How to do that?
Upvotes: 1
Views: 1041
Reputation: 15834
Using 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); }
One way to write a clone function is to make all your descendant classes have defined virtual clone
function, which is abstract in T
. The code of such method is simple, but needs to be defined for every 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));
}
};
With this, the code becomes
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(); }
Note that we have vec2
raw pointers pointing to objects not owned by any smart pointer. This is bad, unless you're passing vec2
into legacy function that takes ownership of these pointers.
Otherwise if you want only a std::vector<T*>
view of the copies, clone into an intermediate std::vector<std::unique_ptr<T>>
, and then copy result of .get()
on each instance to std::vector<T*>
Upvotes: 6
Reputation: 218333
The manual way:
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());
}
with virtual T* T::clone() const
Upvotes: 0