2012-08-16 120 views
4

考慮下面的代碼:繼承和顯式構造函數?

template<typename T> class Base 
{ 
    Base(); 
    Base(const Base<T>& rhs); 
    template<typename T0> explicit Base(const Base<T0>& rhs); 
    template<typename T0, class = typename std::enable_if<std::is_fundamental<T0>::value>::type> Base(const T0& rhs); 
    explicit Base(const std::string& rhs); 
}; 

template<typename T> class Derived : Base<T> 
{ 
    Derived(); 
    Derived(const Derived<T>& rhs); 
    template<class T0> Derived(const T0& rhs) : Base(rhs); 
    // Is there a way to "inherit" the explicit property ? 
    // Derived(double) will call an implicit constructor of Base 
    // Derived(std::string) will call an explicit constructor of Base 
}; 

有沒有辦法來重新設計該代碼的方式使得Derived將有Base用相同的顯式/隱性質的所有構造函數?

+0

繼承構造函數做到這一點。這只是遺憾的是,他們還沒有上,我知道:(我敢肯定,你可以自己動手完成這個任何編譯器實現(性狀檢測隱含/明確地可構造可以很容易地編寫和明智地使用SFINAE可以做剩下的),但我沒有時間到後一個完整的答案,現在,將這樣做,如果沒有一個當我得到的時間晚。 – 2012-08-16 16:12:20

+0

要知道,你的'Derived'無法初始化列表應對。與他們工作的唯一的解決辦法是繼承構建函數。 – 2012-08-16 18:28:43

回答

6

C++ 11個報價this as a feature。但GCC實際上還沒有實現它。

當實際實施,它應該是這樣的:

template<typename T> class Derived : Base<T> 
{ 
    using Base<T>::Base; 
}; 

話雖這麼說,它不能幫助你的情況。繼承的構造函數是一個全有或全無的命題。你得到所有的的基類構造函數,完全使用它們的參數。另外,如果你定義了一個與繼承的簽名相同的構造函數,你會得到一個編譯錯誤。

2

要檢測隱性/明確的可構造爲SFINAE:

template<class T0, typename std::enable_if< 
    std::is_convertible<const T0 &, Base<T>>::value, int>::type = 0> 
    Derived(const T0& rhs) : Base<T>(rhs) { } 
template<class T0, typename std::enable_if< 
    std::is_constructible<Base<T>, const T0 &>::value 
    && !std::is_convertible<const T0 &, Base<T>>::value, int>::type = 0> 
    explicit Derived(const T0& rhs) : Base<T>(rhs) { } 

使用的事實,std::is_convertible檢查隱含兌換和使用std::is_constructible到除了檢查明確的可兌換性。

編輯:固定用溶液從boost::enable_if not in function signatureenable_if模板參數。

檢查:

Derived<int>{5};       // allowed 
[](Derived<int>){}(5);      // allowed 
Derived<int>{std::string{"hello"}};   // allowed 
[](Derived<int>){}(std::string{"hello"}); // not allowed 
+1

的'explicit'構造都可以有其限制在'的std :: is_constructible ,T0常量&> ::值&&!的std :: is_convertible 來表達> :: value'(您也想修復第一個約束:如果參數是'T0常量&',那麼這就是你要覈對與'的std :: is_convertible',不'T0'什麼。) – 2012-08-16 22:12:54

+0

@LucDanton精彩,謝謝。 – ecatmur 2012-08-16 22:21:27