c++ - How to get a type from type_info for template parameters -
i have tree each node looks this:
struct node { std::unordered_set<object*> objects; std::map<std::type_index,node> children; }; when iterate on tree add new type, want check :
std::is_base_of<base,derived> however, information have derived type type_index/type_info*.
is there anyway can transform type_info* template argument?
if not, other options? guess call decltype(*objects.begin()), require each set in every node never empty.
if understood correctly, want type inheritance_checker such each instation of associated type inheritance_checker not. similar type_ifo can check inheritance relationships @ runtime. example, want following work:
class {}; class b : public {}; // note , b have same type "related" distinct types. inheritance_checker = inheritance_checker::create<a>(); inheritance_checker b = inheritance_checker::create<b>(); assert( a.is_base_of (b) ); assert( a.derives_from(a) ); // derives or equal assert( ! b.is_base_of (a) ); assert( b.derives_from(b) ); // derives or equal if case, can suggest that, unfortunately, can quite slow! depends on exceptions.
the basic idea if throw b* catch (a*) match. hence, give inheritance_checker ability throw , catch pointers type given @ construction time. inheritance_checker not template , therefore capacity must provided in type-erased way. can done storing pointers functions have fixed signature doesn't depend on type passed @ construction capable of throwing/catching pointers given type. possible implementation of inheritance_checker given below.
#include <cassert> class inheritance_checker { typedef void (*thrower_t)(); typedef bool (*catcher_t)(thrower_t); public: template <typename t> static inheritance_checker create() { return inheritance_checker(concrete_thrower<t>, concrete_catcher<t>); } bool is_derived_from(const inheritance_checker& other) const { return other.catcher_(thrower_); } bool is_base_of(const inheritance_checker& other) const { return catcher_(other.thrower_); } private: template <typename t> static void concrete_thrower() { throw static_cast<t*>(nullptr); } template <typename t> static bool concrete_catcher(thrower_t thrower) { try { thrower(); } catch (t*) { return true; } catch (...) { } return false; } inheritance_checker(thrower_t thrower, catcher_t catcher) : thrower_(thrower), catcher_(catcher) { } thrower_t thrower_; catcher_t catcher_; }; class {}; class b : public {}; class c : public b {}; class d {}; int main() { auto = inheritance_checker::create<a>(); auto b = inheritance_checker::create<b>(); auto c = inheritance_checker::create<c>(); auto d = inheritance_checker::create<d>(); assert( a.is_base_of(a)); assert( a.is_base_of(b)); assert( a.is_base_of(c)); assert(!a.is_base_of(d)); assert( a.is_derived_from(a)); assert(!a.is_derived_from(b)); assert(!a.is_derived_from(c)); assert(!a.is_derived_from(d)); assert(!b.is_base_of(a)); assert( b.is_base_of(b)); assert( b.is_base_of(c)); assert(!b.is_base_of(d)); assert( b.is_derived_from(a)); assert( b.is_derived_from(b)); assert(!b.is_derived_from(c)); assert(!b.is_derived_from(d)); assert(!c.is_base_of(a)); assert(!c.is_base_of(b)); assert( c.is_base_of(c)); assert(!c.is_base_of(d)); assert( c.is_derived_from(a)); assert( c.is_derived_from(b)); assert( c.is_derived_from(c)); assert(!c.is_derived_from(d)); assert(!d.is_base_of(a)); assert(!d.is_base_of(b)); assert(!d.is_base_of(c)); assert( d.is_base_of(d)); assert(!d.is_derived_from(a)); assert(!d.is_derived_from(b)); assert(!d.is_derived_from(c)); assert( d.is_derived_from(d)); } if wish, might add type_info* member inheritance_checker functionality type_info provides.
notice symmetry between is_base_of , derives_from. actually, can remove 1 of them.
i suggest read this article.
Comments
Post a Comment