Type IDs in C++, a hack

(Note: just use typeid(T). I can’t remember why I didn’t in the first place.)

In a C++ project I needed a way to uniquely identify a type without using reflection. This is what I came up with:

// .h
typedef size_t key_t;
extern key_t max_key;

template <typename T>
inline key_t get_key()
{
    static key_t val = ++max_key;
    return val;
}

// .cpp
key_t max_key;

This works well but this requires run-time static initialisation. The compiler (clang -Os) generated something akin to this:

key = get_key<Foo>();

// ->

if (!get_key__Foo__val_ptr) {
    get_key__Foo__val = ++max_key;
    get_key__Foo__val_ptr = &get_key__Foo__val;
}
key = *get_key__Foo__val_ptr;

If only we had some way to uniquely identify a function, then we wouldn’t need counter variables or static initialisers…

typedef void* key_t;

template <typename T>
inline key_t get_key()
{
    return (key_t)get_key<T>;
}

And behold, it works!

key = get_key<Foo>();

// ->

key = get_key__Foo; // link-time constant

Isn’t life beautiful? The only downside I found so far is that the keys are not sequential.

← back to main