0
我從具有部分專業化的模板繼承,並且我無法從派生的ctor調用模板ctor。模板部分專業化可防止派生類的初始化
當下面的代碼中的部分特化被註釋掉時,它編譯時沒有任何錯誤或警告。
#include <iostream>
typedef enum {supertype, subtype} selector;
template< typename T, selector s>
class Tmpl {
protected:
T* root;
public:
Tmpl(T* t = 0) {
root = t;
}
T listHead() {
std::cout << "template listHead() called" << std::endl;
}
};
class Descriptor {
public:
Descriptor(const char * s) {
std::cout << "Descriptor " << s << std::endl;
}
};
// partial specialization - if uncommented, errors
// are reported at the supertypesIterator ctor below.
/*
template<selector s>
class Tmpl<Descriptor, s> {
public:
Descriptor listHead() {
switch(s){
case supertype:
return Descriptor("Supertypes");
case subtype:
return Descriptor("Subtypes");
}
}
};
*/
class supertypesIterator : public Tmpl<Descriptor, supertype> {
public:
supertypesIterator(Descriptor* t = 0):Tmpl<Descriptor, supertype>(t) {}
};
main() {
supertypesIterator s;
s.listHead();
}
如果我取消了專業化,我收到以下錯誤:
$ g++ trouble.cc
trouble.cc: In constructor ‘supertypesIterator::supertypesIterator(Descriptor*)’:
trouble.cc:43:74: error: no matching function for call to ‘Tmpl<Descriptor, (selector)0u>::Tmpl(Descriptor*&)’
trouble.cc:43:74: note: candidates are:
trouble.cc:27:7: note: Tmpl<Descriptor, (selector)0u>::Tmpl()
trouble.cc:27:7: note: candidate expects 0 arguments, 1 provided
trouble.cc:27:7: note: Tmpl<Descriptor, (selector)0u>::Tmpl(const Tmpl<Descriptor, (selector)0u>&)
trouble.cc:27:7: note: no known conversion for argument 1 from ‘Descriptor*’ to ‘const Tmpl<Descriptor, (selector)0u>&’
什麼我需要做的是能夠從supertypesIterator
中初始化基類構造函數?
我使用g ++版本4.7.1
,但我也需要這個工作跨平臺。
啊哈!幾分鐘前,我嘗試添加ctor Tmpl(描述符* t = 0):Tmpl(t){}'到專門化,但那不起作用(「警告:委託構造函數只適用於......」)。您的版本確實有效。所以模板專門化類似於派生類的處理......我認爲它們不是。 – Mark 2012-07-30 23:02:59
@Mark:模板專業化是您爲您提供的一組參數重新實現模板。所以,如果有很多重疊,它會讓人很失望,但它確實提供了充分的靈活性。 – jxh 2012-07-30 23:09:44
似乎沒有任何方法可以從專業化的構造函數中調用非專用構造函數? – Mark 2012-07-30 23:13:48