aedm
aedm

Reputation: 6594

How to tell if a type is a subclass using type_info?

I use C++ with RTTI. I have a type_info of a class. How can I tell whether another class is a subclass of the first one, if I only have the type_info?

#include <typeinfo>

class Foo             { public: virtual ~Foo() {} };
class Boo: public Foo { public: virtual ~Boo() {} };
class Bar             { public: virtual ~Bar() {} };

template<class T>
bool instanceOf(const type_info& info) {
  // ANSWER COMES HERE!!
}

int main(int argc, const char* argv[]) {
  const type_info& fooInfo = typeid(Foo);
  const type_info& barInfo = typeid(Bar);

  bool booIsFoo = instanceOf<Boo>(fooInfo); // should be true
  bool booIsBar = instanceOf<Boo>(barInfo); // should be false

  return 0;
}

Upvotes: 4

Views: 3165

Answers (1)

Thomas Moulard
Thomas Moulard

Reputation: 5542

If you only have two typeinfo A and B. There is no general way to determine if A is a subclass of B.

You may:

  1. store this information by yourself (static structure filled at runtime?)
  2. make educated guesses using the type name (i.e. parsing the type info string and name the types accordingly).

Previous answers. They require you to instantiate the type somehow:

type_info is not the right tool for this, you should dynamic_cast if you absolutely want to check at runtime:

template<class Base, typename Derived>
bool instanceOf(const Derived& object) {
  return !dynamic_cast<Base*>(object);
}

You can also check at compile time using std::is_base_of as Steephen mentioned (C++11 needed).

template <typename Base, typename Derived>
static constexpr bool instanceOf() {
    return std::is_base_of<Base, Derived>()
}

Another solution:

template <typename Base, typename Derived>
bool instanceOf(const Derived& object) {
  try {
      throw object;
  } catch (const Base&) {
      return true;
  } catch (...) {
      return false;
  }
}

Upvotes: 5

Related Questions