15

The typeid operator in C++ returns an object of class std::type_info which can yield its textual name. However, I'm just interested in getting an unique numeric identifier for any polymorphic class. (unique in the scope of a single program run - not necessarily between runs)

In practice, I could just dereference the pointer and read the vptr's contents - but this would be neither elegant nor portable. I prefer a portable way.

Can I use the typeid operator somehow to have a "safe" numerical identifier for a class? For example, can I count on the address of resulting std::type_info structure to be the same for every typeid call on a given class? Or perhaps the name() pointer itself?

Kos
  • 70,399
  • 25
  • 169
  • 233
  • You could calculate a hash on the typeid's name. Since this is a string literal, it should be resolved at compile time too. At least that's what the "Gem" where I got that idea from says... my experience is different. For me, the overhead of that solution is inacceptably high. But well, it's certainly portable, so... yeah. – Damon Apr 19 '11 at 17:02
  • What problem are you actually trying to solve here? – Mark B Apr 19 '11 at 17:05
  • The problem of me trying to resist casting the object's address to `void**` and dereferencing it for the vptr. :D And more seriously- something akin to a 2-dimensional vtable. – Kos Apr 19 '11 at 17:07
  • The address of type_info structs will be unique for single modules yes, but afaik at least on windows, its not safe to use this for types of more than 1 module (application/dynamic libraries). – smerlin Apr 19 '11 at 17:25

4 Answers4

9

std::type_index (C++ 11) can be used in containers to store values based on type. It won't give you a number though.

std::type_index index = std::type_index (typeid (int));

More: http://en.cppreference.com/w/cpp/types/type_index

The type_index class is a wrapper class around a std::type_info object, that can be used as index in associative and unordered associative containers. The relationship with type_info object is maintained through a pointer, therefore type_index is CopyConstructible and CopyAssignable.

Kos
  • 70,399
  • 25
  • 169
  • 233
lietus
  • 199
  • 2
  • 11
4

The type_info has an operator==() for comparing the type it describes to the type of another type_info object. The objects are also guaranteed to outlive the program.

So if you save the addresses of two type_infos, you could get away with *p1 == *p2 to see if they refer to the same type.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
0

static data member that is initialized with an algorithm that uses a counter? Then use MyClass::id as the unique identifier. And then use virtual functions to fetch the unique identifier based on baseclass. Guaranteed to be portable, but has slight maintainance burden since you need to implement both the static variable and implement the virtual function for every new class you create. But guess that's not a big problem since you've already chosen to use c++, which is known to be verbose. It would look like this:

class Base { virtual int get_id() const=0; };
class Derived : public Base { static int id; int get_id() const { return id; } };
int algo() { static int count=0; count++; return count; }
static int Derived::id = algo();
tp1
  • 288
  • 1
  • 3
  • 2
    It's possible, but wasn't RTTI invented for exactly the purpose that I wouldn't need to write and maintain such code? It's the compiler's job to do it, not mine. – Kos Apr 19 '11 at 17:09
  • well, the point is that in c++ you really get better code sometimes if you actually do the work and write slightly larger amount of boilerplate code. – tp1 Apr 19 '11 at 17:14
0

Looks like type_info::hash_code() is prescribed for C++0x.

paquetp
  • 1,639
  • 11
  • 19
  • 10
    Caution! Per standard: hash_code() does not need to return different ids for two different types. It is a hash code not a key. – Christopher Oezbek Nov 24 '11 at 12:07
  • Also this has a cost. I made a few tests and `hash_chode` is much slower than using `type_index` – 56ka Jan 14 '20 at 17:08