Lets say that I have a base and derived class, and a function that takes an stl vector of pointers to the base class:
class A { public: int x; };
class B :
As @Science_Fiction said earlier, it makes more sense to have a vector that holds pointers to the basic type and insert pointers to both basic and derived types into it, but if you don't control the creation of these arrays, you can use templates:
template <class T>
inline void foo(const vector<T*>& v)
{
for (vector<T*>::const_iterator it = v.begin(); it < v.end(); ++it)
{
A* a = (A*) *it;
cout << a->x << endl;
}
}
You cannot pass a vector<B*>
to foo
because the types are incompatible -- it doesn't make a difference that B*
is implicitly convertible to A*
.
What you can do is create a new vector
of the correct type, which is possible with, for example:
vector<B*> vb;
// ... add pointers to vb ...
vector<A*> va(vb.size());
std::transform(vb.begin(), vb.end(), va.begin(),
[] (B* p) { return static_cast<A*>(p); });
std::vector<B*> and std::vector<A*>
are technically unrelated. C++ does not allow what you want as such.
A way around...Why not have a std::vector<Base*>
and insert into it Derived
objects? That is the point of polymorphism, dynamic dispatch et al.
You can create temporary vector of base pointers from vector of derived base pointers:
std::vector<B*> bv;
foo(std::vector<A*>(bv.begin(), bv.end()));
But this requires that foo accepts const reference not reference like in your example, and it is very inefficient, requires memory allocation and copying,
Other, preferred solution is to make your foo a function template:
template <class T>
void foo(std::vector<T*>& v);
To be sure that foo
will be used only for A derived, use type_traits and SFINAE technique, note that you call foo
only with first argument, the second is only for eliminating this function template for types not derived from A (SFINAE):
#include <type_traits>
template <class T>
void foo(std::vector<T*>& av,
// don't use this second param
typename std::enable_if<std::is_base_of<A,T>::value>::type* = 0)