4
我有一個派生自某個基類的類的註冊器的實現。目的是讓每個派生類自己註冊,並且在這個過程中提供一些關於它自己的信息,在下面的例子中是通過一個字符串提供的。強制派生類型的註冊
我缺少的是強制從Base
派生的類通過初始化靜態成員reg
註冊自己的方法。換句話說,如果派生類沒有定義/初始化靜態成員,是否有可能讓編譯器產生錯誤? void blah() { }
然後從CRTP基類的一個虛設的構造調用它:
public:
Base() { reg.blah(); }
我可以
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;
}
最好我能想到的是一個鏈接器錯誤(不是編譯錯誤),唯一的方法就是以某種方式訪問'Base'類中的'reg'(比如在構造函數中) - 這應該觸發一個鏈接器錯誤(與您確實使用的派生類型有問題的地方...) – Nim
@Nim:我想的完全一樣;-) – Nawaz