There have been a few questions about static data members of template classes not being initialized. Unfortunately none of these had answers that were able to help me with my specific problem.
I have a template class that has a static data member that must be instantiated explicitly for specific types (i.e., must be specialized). If this is not the case, using a different template function should cause a linker error.
Here's some code:
#include <iostream>
template <typename T>
class Instantiate {
public:
static Instantiate instance;
private:
Instantiate(std::string const &id) {
std::cout << "Instantiated " << id << "." << std::endl;
// Additional, important side effects...
}
};
template <typename T>
void runme() {
// Do something to ensure instance is instantiated,
// without creating run-time overhead.
// The following only works without optimization.
void *force = &Instantiate<T>::instance;
}
// Instances need to be explicitly specialized for specific types.
template <> Instantiate<int> Instantiate<int>::instance = {"int"};
int main() {
// This is OK, since Instantiate<int>::instance was defined.
runme<int>();
// This should cause a (linker) error, since
// Instantiate<double>::instance is not defined.
runme<double>();
}
Calling runme<T>
should require that Instantiate<T>::instance
is defined, without actually using it. Getting a pointer to instance
as shown works - but only if no optimizations are enabled. I need a different method that works with at least O2
, and also works if the instantiation of instance
occurs in a different compilation unit.
Question:
How can I ensure that I get a linker error when calling runme
with a type T
for which no explicit Instantiate<T>::instance
has been defined/specialized?