Given the following:
template
class A
{
public:
static const unsigned int ID = ?;
};
I want ID to generate a unique c
Another alternative is to consider the following class Data
with the unique, static member field type
:
template <class T>
class Data
{
public:
static const std::type_index type;
};
// do [static data member initialization](http://stackoverflow.com/q/11300652/3041008)
// by [generating unique type id](http://stackoverflow.com/q/26794944/3041008)
template <class T>
std::type_index const Data<T>::type = std::type_index(typeid(T));
produces the output (MinGWx64-gcc4.8.4 -std=c++11 -O2
)
printf("%s %s\n", Data<int>::type.name(), Data<float>::type.name())
//prints "i f"
It's not exactly an integer id or pretty-printable string, nor a constexpr
, but can be used as an index in (un)ordered associative containers.
It also appears to work if the Data.h
header is included in multiple files (same hashCode()
values).
I encountered this exact problem recently. My solution:
counter.hpp
class counter
{
static int i;
static nexti()
{
return i++;
}
};
Counter.cpp:
int counter::i = 0;
templateclass.hpp
#include "counter.hpp"
template <class T>
tclass
{
static const int id;
};
template <class T>
int tclass<T>::id = counter::nexti();
It appers to work properly in MSVC and GCC, with the one exception that you can't use it in a switch statement.
For various reasons I actually went further, and defined a preprocessor macro that creates a new class from a given name parameter with a static ID (as above) that derives from a common base.
template<typename T>
static void get_type_id() { void* x; new (x) T(); }
using type_id_t = void(*)();
works fine with optimizations
This can't be done. An address to a static object is the closest you can get to a unique id, however in order to take addresses of such objects (even static const integrals) they must be defined somewhere. Per the one definition rule, they should be defined within a CPP file, which cannot be done since they are templates. If you define the statics within a header file, then each compilation unit will get its own version of it implemented of course at different addresses.