4

我有一个从某个基类派生的类的注册器实现。目的是让每个派生类注册自己,并在此过程中提供一些关于自身的信息,在下面的示例中,这些信息是通过字符串提供的。

我缺少的是一种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;
}
4

1 回答 1

1

您至少可以通过向注册器添加一个虚拟函数来导致 g++ 中的链接器错误:void blah() { }然后从 CRTP 基类中的虚拟构造函数调用它:

public:
    Base() { reg.blah(); }

我找不到更优雅的方法来解决这个问题。

于 2013-01-22T18:33:37.170 回答