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

少なくともレジストラにダミー関数を追加void blah() { }し、CRTP基本クラスのダミーコンストラクタからそれを呼び出すことによって、g++でリンカエラーを引き起こす可能性があります。

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

この問題を解決するためのよりエレガントな方法は見当たりません。

于 2013-01-22T18:33:37.170 に答える