C++: type_info to distinguish types

peoro picture peoro · Nov 16, 2010 · Viewed 18.2k times · Source

I know that compilers have much freedom in implementing std::type_info functions' behavior.

I'm thinking about using it to compare object types, so I'd like to be sure that:

  1. std::type_info::name must return two different strings for two different types.

  2. std::type_info::before must say that Type1 is before Type2 exclusive-or Type2 is before Type1.

    // like this:
    typeid(T1).before( typeid(T2) ) != typeid(T2).before( typeid(T1) )
    
  3. Two different specialization of the same template class are considered different types.

  4. Two different typedef-initions of the same type are the same type.

And finally:

  • Since std::type_info is not copyable, how could I store type_infos somewhere (eg: in a std::map)? The only way it to have a std::type_info always allocated somewhere (eg: on the stack or on a static/global variable) and use a pointer to it?

  • How fast are operator==, operator!= and before on most common compilers? I guess they should only compare a value. And how fast is typeid?

  • I've got a class A with a virtual bool operator==( const A& ) const. Since A has got many subclasses (some of which are unknown at compile time), I'd overload that virtual operator in any subclass B this way:

    virtual bool operator==( const A &other ) const {
      if( typeid(*this) != typeid(other) ) return false;
      // bool B::operator==( const B &other ) const // is defined for any class B
      return operator==( static_cast<B&>( other ) );
    }
    

    Is this an acceptable (and standard) way to implement such operator?

Answer

Opera picture Opera · Nov 16, 2010

After a quick look at the documentation, I would say that :

  1. std::type_info::name always returns two different strings for two different types, otherwise it means that the compiler lost itself while resolving types and you shouldn't use it anymore.

  2. Reference tells : "before returns true if the type precedes the type of rhs in the collation order. The collation order is just an internal order kept by a particular implementation and is not necessarily related to inheritance relations or declaring order." You therefore have the guarantee that no types has the same rank in the collation order.

  3. Each instantiation of a template class is a different type. Specialization make no exceptions.

  4. I don't really understand what you mean. If you mean something like having typedef foo bar; in two separate compilation units and that bar is the same in both, it works that way. If you mean typedef foo bar; typedef int bar;, it doesn't work (except if foo is int).

About your other questions :

  • You should store references to std::type_info, of wrap it somehow.
  • Absolutely no idea about performance, I assume that comparison operators have constant time despite of the type complexity. Before must have linear complexity depending on the number of different types used in your code.
  • This is really strange imho. You should overload your operator== instead of make it virtual and override it.