2015-09-03 68 views
1

我有一個模板構造函數的類:模板構造函數中使用派生類

class TCons { 
    template <typename T> TCons(T t); 
} 

是一家專業的實現:

template <> TCons::TCons(int i) { doMyStuff(i); } 

我也有一個基類的特化:

template <> TCons::Tcons(TBase &t) { doMyStuff(t); } 

但是,當我嘗試使用派生對象初始化一個TCons對象時,這似乎不起作用作爲參數。

class TDeriv: public TBase { }; 
TDeriv td; 
TCons tc = td; 

我不能使用指針來解決這個問題(因爲一切都被包裝在一個宏內)。問題出現在鏈接階段。

這是錯誤的,還是我錯過了什麼?

+1

修復拼寫錯誤和語法,以便編譯代碼。 – user2079303

+1

爲什麼使用專業化而不是簡單的重載? – Jarod42

+0

失去'template <>' –

回答

5

當我們試圖構建tc這裏:

TCons tc = td; 

我們有一個選擇的構造函數:

template <typename T> TCons(T t); 

當我們執行模板扣,我們推斷T = TDeriv。這不是不是匹配你的TBase明確的專業化(也不是int之一),所以我們堅持與主要模板。您不提供它的定義,這就是爲什麼你有鏈接器錯誤。

如果您希望對所有從TBase繼承的類型調用TBase構造函數,則必須爲這些情況禁用構造函數模板。我們可以做到這一點SFINAE:

template <typename T, 
      typename = std::enable_if_t<!std::is_base_of<TBase, T>::value>> 
TCons(T); 

,同時還讓您的其他構造非模板重載:

TCons(int); 
TCons(TBase&); 

只有當你需要專注 - 超載是要簡單。

+0

解決了,但鏗鏘語法有點不同:template :: value> :: type> –

+0

@GB這不是「鏗鏘語法」,那就是C++ 11。即使您沒有C++ 14編譯器,您也應該自己添加類型特徵別名 - 使代碼更清晰。 – Barry

+0

C++概念確實會使代碼更清晰。現在它看起來像一列火車殘骸...... –

相關問題