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,但我也需要這個工作跨平臺。

回答

2

您必須在專業化中實施缺少的構造函數。否則,supertypesIterator的構造函數正在嘗試調用不存在的Tmpl的構造函數。

template<selector s> 
class Tmpl<Descriptor, s> { 
    Descriptor* root; 
public: 
    Tmpl(Descriptor* t = 0) { 
     root = t; 
    } 
    Descriptor listHead() { 
     switch(s){ 
      case supertype: 
       return Descriptor("Supertypes"); 
      case subtype: 
       return Descriptor("Subtypes"); 
     } 
    } 
}; 
+0

啊哈!幾分鐘前,我嘗試添加ctor Tmpl(描述符* t = 0):Tmpl(t){}'到專門化,但那不起作用(「警告:委託構造函數只適用於......」)。您的版本確實有效。所以模板專門化類似於派生類的處理......我認爲它們不是。 – Mark 2012-07-30 23:02:59

+0

@Mark:模板專業化是您爲您提供的一組參數重新實現模板。所以,如果有很多重疊,它會讓人很失望,但它確實提供了充分的靈活性。 – jxh 2012-07-30 23:09:44

+0

似乎沒有任何方法可以從專業化的構造函數中調用非專用構造函數? – Mark 2012-07-30 23:13:48