Numeric unique identifier of a class via typeid
Asked Answered
G

4

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?

Graham answered 19/4, 2011 at 16:54 Comment(4)
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.Fullback
What problem are you actually trying to solve here?Shere
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.Graham
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).Shanty
P
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.

Photocathode answered 6/10, 2014 at 10:48 Comment(0)
J
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.

Jaella answered 19/4, 2011 at 17:28 Comment(0)
K
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();
Kendrick answered 19/4, 2011 at 17:6 Comment(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.Graham
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.Kendrick
E
0

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

Ettore answered 19/4, 2011 at 17:15 Comment(2)
Caution! Per standard: hash_code() does not need to return different ids for two different types. It is a hash code not a key.Hueyhuff
Also this has a cost. I made a few tests and hash_chode is much slower than using type_indexKumquat

© 2022 - 2024 — McMap. All rights reserved.