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