What, if any, c++ constructs are there for listing the ancestors of a class at runtime?
Basically, I have a class which stores a pointer to any object, including possibly a primitive type (somewhat like boost::any
, which I don't want to use because I need to retain ownership of my objects). Internally, this pointer is a void*
, but the goal of this class is to wrap the void*
with runtime type-safety. The assignment operator is templated, so at assignment time I take the typeid()
of the incoming pointer and store it. Then when I cast back later, I can check the typeid()
of the cast type against the stored type_info
. If it mismatches, the cast will throw an exception.
But there's a problem: It seems I lose polymorphism. Let's say B
is a base of D
. If I store a pointer to D
in my class, then the stored type_info
will also be of D
. Then later on, I might want to retrieve a B
pointer. If I use my class's method to cast to B*
, then typeid(B) == typeid(D)
fails, and the cast raises an exception, even though D->B
conversion is safe. Dynamic_cast<>()
doesn't apply here, since I'm operating on a void*
and not an ancestor of B
or D
.
What I would like to be able to do is check is_ancestor(typeid(B), typeid(D))
. Is this possible? (And isn't this what dynamic_cast<>
is doing behind the scenes?)
If not, then I am thinking of taking a second approach anyway: implement a a class TypeInfo
, whose derived classes are templated singletons. I can then store whatever information I like in these classes, and then keep pointers to them in my AnyPointer
class. This would allow me to generate/store the ancestor information at compile time in a more accessible way. So failing option #1 (a built-in way of listing ancestors given only information available at runtime), is there a construct/procedure I can use which will allow the ancestor information to be generated and stored automatically at compile-time, preferably without having to explicitly input that "class A
derives from B
and C
; C
derives from D
" etc.? Once I have this, is there a safe way to actually perform that cast?
typeid(A) == typeid(B)
; in fact, that's where I got the idea! – Walrusplaceholder
and atemplate<class ValueType> holder : placeholder
with pure virtual functions to store the actual type. That's why there solution is able to handle polymorphism. – Kallytypeinfo
et virtuality ? Neither do I. Encoding the base classes (somehow) in the derived class, I do, but it gets cumbersome. – Notustype_info
, but he does handle polymorphism! You should probably be accepting his. – Notus