I found a way I think is good for keeping track of which templates have been instantiated in my program, and I find this really useful for me:
constinit const char* loggerTypesCreated[32];
int count = 0;
template <typename T>
struct MyLogger
{
static inline char usedVariable = rand();
static inline char dummy = []()
{
loggerTypesCreated[count] = typeid(T).name();
++count;
return char(); // dummy
}();
};
int main()
{
MyLogger<int>{}, MyLogger<char>{}, MyLogger<double>{}, MyLogger<float>{};
std::cout << "Loggers created:\n";
for (int i = 0; i < count; ++i)
std::cout << "Logger<" << loggerTypesCreated[i] << ">\n";
}
Though the array and the static dummy
in the class are both static, initialization order are defined because the array is 'constant' initialized. You could do this with an std::vector
too as far as I know because the default constructor is constexpr
, and initialized constantly.
Anyway, for me running a function at the start of the program in a way like above is really useful for me for registering the types I've created, but is there a way to do this without a dummy
variable?
Furthermore, does the dummy
variable risk getting optimized out because it's not used? Its initializer has a side effect, but I don't know if it matters.
This works great for me for a lot of things, including placing timers in functions.
Edit: In case it's not clear, I don't want the initialiser function to be called when creating an object, I want it like this:
void functionToBeTimed
{
Timer</a_unique_type/> timer;
// Not when the object is created, but at program startup
// to initialise all instantiated templates.
}