Is there a way to achieve the same result using a C++ construct, such
as templates?
Yes, there is :-) The basic idea is to use chaining allocated IDs, which avoids the use of __COUNTER__
, __LINE__
or other approaches proposed earlier and does not require injecting "extra" info into the type definition.
Here is a brief description of the solution proposed in v1 for the counter implemented on C++03, using template metaprograming. Two template specializations ID_by_T
and T_by_ID
are used to define links type <=> ID
at compile time. The type's ID is a enum constant. If the link was not defined, ID_by_T<type>::ID
returns -1
, and T_by_ID<undefinedID>::type
returns the null_t
predefined type. The macro DEF_TYPE_ID(type_name)
generates a new ID
at the point of the definition the type <=> ID
link.
This approach is based on a macro redefinition: When a macro is undefined using #undef
, its value is expanded into the C++ code. For instance:
DEF_TYPE_ID(int)
#undef PREV_TYPE
#define PREV_TYPE int
Macro DEF_TYPE_ID
uses the following call to the previous definition of macro PREV_TYPE
: ID_T_pair<type_name, ID_by_T<PREV_TYPE>::ID+1>
. That is why I said about chaining allocated IDs.