I have an implementation of a registrar for classes that are derived from a certain base class. The intent is to have each derived class register itself and in the process provide some information about itself, which in the example below is provided through a string.
What I’m missing is a way to force classes that derive from Base to register themselves through initializing the static member reg. In other words, is it possible to have the compiler somehow produce an error if a derived class doesn’t define/initiatlize the static member?
struct Registrar {
Registrar(string type) {
registry().push_back(type);
}
static vector<string> & registry() {
static vector<string> * derivedTypes = new vector<string>;
return *derivedTypes;
}
};
//CRTP
template <typename Derived>
class Base
{
static Registrar reg;
};
class Derived1 : public Base<Derived1> {/*Class definition*/};
class Derived2 : public Base<Derived2> {/*Class definition*/};
class Derived3 : public Base<Derived3> {/*Class definition*/};
//...
//Initialize the static members of each derived type
//Commenting out any of the following 3 lines doesn't produce an error.
//Ideally, I want it to produce a compile error.
template<> Registrar Base<Derived1>::reg("Derived1");
template<> Registrar Base<Derived2>::reg("Derived2");
template<> Registrar Base<Derived3>::reg("Derived3");
int main() {
cout << "Registered Types:" << endl;
for(vector<string>::const_iterator it = Registrar::registry().begin();
it != Registrar::registry().end(); ++it) {
cout << *it << endl;
}
return 0;
}
You can cause a linker error in g++ at least by adding a dummy function to the registrar:
void blah() { }and then calling it from a dummy constructor in the CRTP base class:I can’t see a more elegant way to solve this problem.