Following my answer to Unique type ID in C++, I have worked towards a safer version that I am posting here.This is a lightweight type that can store a unique (also across compilation units) ID per type for use at runtime, without RTTI.Instead of using a built-in type for ID representation that is also accessible to the end user, a specific class type_id_t provides the external representation of the ID and encapsulates the actual storage type (a function pointer) that is not accessible.A helper function template call type_id<T>() returns a type_id_t containing the ID of type T.Hence, the following operations are only provided:construction only by calling type_id function.copy/move construction, as implicitly definedcopy/move assignment, as implicitly definedcomparison operators == and != between two type_id_t'sThere is no default constructor for type_id_t.Here is the implementation:class type_id_t{    using sig = type_id_t();    sig* id;    type_id_t(sig* id) : id{id} {}public:    template<typename T>    friend type_id_t type_id();    bool operator==(type_id_t o) const { return id == o.id; }    bool operator!=(type_id_t o) const { return id != o.id; }};template<typename T>type_id_t type_id() { return &type_id<T>; }It is interesting that function type_id returns a (function) pointer to itself, encapsulated into a type_id_t. No nasty type casting is necessary.This is not a mechanism that provides runtime identification of a (polymorphic) object's type, but can be used as a low-level tool to build such functionality. I actually made this for the needs of my recent any, and then improved it.Just for demonstration, we can store the ID of a number of types e.g. in a vector:template<typename... T>std::vector<type_id_t>make_ids() { return {type_id<T>()...}; }Later, we can compare the stored IDs to the ID of a given type:template<typename T, typename A>void comp_ids(const A& a){    for (auto i : a)        std::cout << (type_id<T>() == i) <<  ;    std::cout << std::endl;}and get the following:auto ids = make_ids<    int, bool, double const&, int&&, char(&)[8],    int, void(int), unsigned char**, std::vector<void(*)()>, double[4][8]>();comp_ids<int>(ids);  // output: 1 0 0 0 0 1 0 0 0 0Here is a live example.Any comments are welcome.
Unique type ID, no RTTI
c++;c++11;rtti