Вот как бы я это сделал:
вместо использования скалярного типа для идентификатора типа, например так:
static const uint64_t type_id = 0x0;
Я бы создал выделенный тип с конструктором :
static const my_meta_type type_id;
my_meta_type A::type_id{0x00};
Где my_meta_type
будет выглядеть примерно так:
class my_meta_type {
static std::vector<my_meta_type const*>& registered_types(); //Meyer's singleton
uint64_t id_;
public:
my_meta_type(uint64_t id)
: id_(id) {
registered_types().emplace_back(this);
}
};
std::vector<my_meta_type*>& my_meta_type::registered_types() {
static std::vector<my_meta_type const*> instance;
return instance;
}
Что это будет делать, так это то, что во время инициализации будут выполняться конструкторы my_meta_type
, помещая экземпляры указателя в vector<my_meta_type*>
. Поскольку все это происходит во время инициализации, мы должны убедиться, что порядок инициализации не вызывает у нас проблем, поэтому мы используем синглтон Мейера для разрешения потенциальных конфликтов.
Оттуда все, что вам нужно сделать, это получить идентификаторы из вектора во время выполнения программы.