So, lets start with the code that does what I want, but I'd like to teach it a new trick (if it is possible).
#include <string>
#include <iostream>
class A {}; class B {}; class C {}; class D {};
template<typename T> struct traits { };
template<> struct traits<A> { static std::string code() {return "class A";}};
template<> struct traits<B> { static std::string code() {return "class B";}};
template<> struct traits<C> { static std::string code() {return "class C";}};
template<> struct traits<D> { static std::string code() {return "class D";}};
std::string RegisterClass(const std::string & c){
std::cout << "Registering " << c << '\n';
return c;
}
template<typename T> void printMe() {
static std::string t = RegisterClass(traits<T>::code());
std::cout << "Printing " << traits<T>::code() << '\n';
}
int main(void)
{
printMe<B>();
printMe<B>();
printMe<C>();
return 0;
}
The output of it is as one might expect -- the "registration" happens only once and only for those types that the template was instantiated with:
Registering class B
Printing class B
Printing class B
Registering class C
Printing class C
What I would like to have is to have only the classes that was used to "register" themselves before the first call to the printMe
function. So the output would look like this:
Registering class B
Registering class C
Printing class B
Printing class B
Printing class C
Superficially, that seems possible. The compiler "knows" which types was used for instantiation . If I were able to store that information in some global or static thingy, then I'd just process it at the beginning of main()
.
But all my attempts to subvert the compiler into actually doing it have failed so far. Which made me suspect that it is intentional. So 'Can I have template instantiation side-effects? ' he asked, expecting the answer 'no'?
Edit: I'm sorry, but I've really failed to clearly express myself in that sentence. In the example above I don't need the registration for A,B,C and D
-- I need it only for B and C
and I want the compiler to figure that out by himself somehow.