我有一个针对从某个基类派生的类的注册器的实现。目的是让每个派生类自己注册并在此过程中提供一些关于自身的信息,在下面的例子中通过字符串提供。
我缺少的是一种强制从Base
派生的类通过初始化静态成员reg
来注册自己的方法。换句话说,如果派生类没有定义/初始化静态成员,是否有可能让编译器以某种方式产生错误?
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;
}
答案 0 :(得分:1)
至少可以通过向注册器添加虚函数来导致g ++中的链接器错误:void blah() { }
然后从CRTP基类中的虚拟构造函数调用它:
public:
Base() { reg.blah(); }
我看不出更优雅的方法来解决这个问题。