My problem could be described with the example below.
I want to call a static function from each instantiation of a template. What I am thinking of is something like a tuple which gets expanded each time a new instantiation of a template is encountered, so that I can access that tuple recursively and call a static function of each of the types in the tuple.
#include <vector>
template<typename T>
struct Junk
{
static std::vector<T> all;
Junk(T t)
{
all.push_back(t);
}
static void clear()
{
all.clear();
}
};
template<typename T>
std::vector<T> Junk<T>::all;
void clearJunk()
{
Junk<float>::clear();
Junk<char>::clear();
Junk<unsigned int>::clear();
// how can I generalize this?
}
int main()
{
// instantiate Junk with different types
Junk<float> f1(1.0f);
Junk<float> f2(2.0f);
// Junk<float>::all.size() == 2
Junk<char> c1('a');
Junk<char> c2('b');
Junk<char> c3('c');
// Junk<char>::all.size() == 3
Junk<unsigned int> i1(1);
// Junk<unsigned int>::all.size() == 1
// clear all Junk
clearJunk();
return 0;
}
A run-time solution to this would be a vector of function pointers, and the first object of each template instantiation pushes a pointer to the static member function to that vector:
std::vector<void(*)()> clear_funcs;
template<typename T>
struct Junk
{
static std::vector<T> all;
Junk(T t)
{
(void)init; // mention init at least once so its constructor will be invoked
all.push_back(t);
}
static void clear()
{
all.clear();
}
struct At_Init
{
At_Init()
{
clear_funcs.push_back(&Junk<T>::clear);
}
};
static At_Init init; // will only be constructed once for each template instantiation
};
template<typename T>
std::vector<T> Junk<T>::all;
template<typename T>
typename Junk<T>::At_Init Junk<T>::init;
void clearJunk()
{
// call every clear() of all the Junk template instantiations
for (void(*clear)() : clear_funcs) {
clear();
}
}
But this solution is not as fast as a compile time solution would be and it requires a lot of code in the class that is not at all meaningful, so I dislike this solution, although it works.
How could you generate code at compile-time to call a static function of every instantiation of a template?