Basically I've a class A and a class B : public A.
And I'd like to cast a std::shared_ptr<std::vector<A*> to a std::shared_ptr<std::vector<B*>
The problem is std::vector<B> doesn't inherit from std::vector<A>, and the smart_ptr neither. So I do a horrible cast:
std::shared_ptr<VectorA> vector_a = * ((std::shared_ptr<VectorA>*)&vector_b);
The code compiles and runs there, but it is safe? http://liveworkspace.org/code/3dQTz1$0
This is a horrible solution. When you cast a vector of objects of one type to the other you can expect all kind of incorrect/undefined behaviour.
You should use vector of std::shared_ptr<A> from the beginning and initialize them with pointers to objects of type B there.
If it is not possible you can create a new vector holding std::weak_ptr<A> to avoid managing these objects twice.
Don't do that.
Consider that a vector of (pointers to) B is not a vector of (pointers to) A, or to be more precise, is not a universally valid substitution for a vector of (pointers to) A; thus, there is a good reason why you cannot perform such a conversion.
Although it is true that all you have in a vector of B is indeed a set of objects which are (also( instances of A, consider the following algorithm:
void f(vector<A>& v)
{
A a;
v.push_back(a);
}
Now imagine you invoke f() with a vector of B. That would be an attempt to add an instance of a class that is not B to a collection which is supposed to contain only elements of type B.
The solution here is to make the code which accepts only a vector<A> flexible enough to work also on a vector<B>. In other words, you need to make it a template. For instance, your template could accept as arguments only vectors of a type which is derived from A. This is quite easy to enforce with some SFINAE techniques and type traits such as std::is_base_of.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With