I have a class Base
:
class Base
{
};
and a derived class Derived
:
class Derived: public Base
{
};
Now I need to get a vector of Derived Pointers:
std::vector<std::shared_ptr<Derived>> derivedVec;
but they are stored unfortunately as a vector of Base Pointers, e.g. I can access only the downcasted pointers:
std::vector<std::shared_ptr<Base>> baseVec;
How to I perform the conversion from std::vector<std::shared_ptr<Base>>
to std::vector<std::shared_ptr<Derived>>
. The solution is desired to be C++20 style.
Firstly, two vectors std::vector<A>
and std::vector<B>
aren't covariant, meaning that it's not enough to reinterpret one as the other. To get a std::vector<std::shared_ptr<Derived>>
, you need to convert the vector:
#include <vector>
#include <memory>
#include <ranges>
// ...
std::vector<std::shared_ptr<Base>> base;
auto derived_view = base | std::views::transform([](const std::shared_ptr<Base> &b) {
// or use std::dynamic_pointer_cast for polymorphic classes
return std::static_pointer_cast<Derived>(b);
});
// If you don't need to create a new vector, but just want to examine the old one
// with the conversion applied, you can also skip this step and work with the view.
std::vector<std::shared_ptr<Derived>> derived(derived_view.begin(), derived_view.end());
// In C++23, you can also write:
std::vector<std::shared_ptr<Derived>> derived(std::from_range, derived_view);
// however, not every standard library supports this yet, at the time of writing