2016-11-10 61 views
1

給定一個模板類A,我想定義取決於A的模板參數T_lhsT_rhs類型T_res類型定義應該依賴於模板參數

template< typename T_lhs, typename T_rhs > 
class A 
{ 
    // definition of T_res in case "T_lhs and T_rhs are both not primitive types" 
    template< bool lhs_is_fundamental = std::is_fundamental<T_lhs>::value, 
      bool rhs_is_fundamental = std::is_fundamental<T_rhs>::value, 
      std::enable_if_t<(!lhs_is_fundamental && !rhs_is_fundamental)>* = nullptr > 
    using T_res = decltype(std::declval<T_lhs>().cast_to_primitive()/std::declval<T_rhs>().cast_to_primitive()); 

    // definition of T_res in case "T_lhs and/or T_rhs is a primitive type" 
    template< bool lhs_is_fundamental = std::is_fundamental<T_lhs>::value, 
      bool rhs_is_fundamental = std::is_fundamental<T_rhs>::value, 
      std::enable_if_t<(lhs_is_fundamental || rhs_is_fundamental)>* = nullptr > 
    using T_res = decltype(std::declval<T_lhs>()/std::declval<T_rhs>()); 

    // ... 
}; 

在第一種情況下,如果T_lhsT_rhs都不是原始類型,我的代碼是這樣設計的,它們表示實現函數cast_to_primitive()的類,它返回一個原始類型;在這第一種情況下,我想要T_res的類型是通過decltype(std::declval<T_lhs>().cast_to_primitive())類型的元素除以decltype(std::declval<T_rhs>().cast_to_primitive())類型的元素而獲得的。

在第二,其中任T_lhsT_rhs是基本類型(或甚至兩個),我想T_res到具有由由類型T_rhs的元素除以T_lhs類型的元素而獲得的類型。例如,在T_lhs是原始類型的情況下,我的代碼設計得可以將T_rhs隱式轉換爲T_lhs類型的元素;在T_rhs是原始的情況下也是如此。

不幸的是,上面的代碼不能編譯。錯誤:

error: template non-type parameter has a different type 'std::enable_if_t<(lhs_is_fundamental || rhs_is_fundamental)> *' (aka 'typename enable_if<(lhs_is_fundamental || rhs_is_fundamental), void>::type *') in template redeclaration 
      std::enable_if_t<(lhs_is_fundamental || rhs_is_fundamental)>* = nullptr > 
                      ^
note: previous non-type template parameter with type 'std::enable_if_t<(!lhs_is_fundamental && !rhs_is_fundamental)> *' (aka 'typename enable_if<(!lhs_is_fundamental && !rhs_is_fundamental), void>::type *') is here 
      std::enable_if_t<(!lhs_is_fundamental && !rhs_is_fundamental)>* = nullptr > 
                      ^

有人可以幫我解決這個問題嗎?

+0

' std :: conditional_t <..>'可能會有所幫助。 – Jarod42

+0

這將有助於瞭解你的課堂'A'的目的是什麼。 – Rerito

回答

3

這大約是在Using std::conditional_t to define a class' typedef in dependence of its template parameter

的解決方案是使用與輔助類std::conditional耽誤師/調用cast_to_primitive的實例,直到發現了同樣的問題std::conditional實例化後:

#include <type_traits> 

template<class T1, class T2> 
struct A 
{ 
    template<class T=T1, class U=T2> 
    struct cast_to_primitive_t {using type=decltype(std::declval<T>().cast_to_primitive()/std::declval<U>().cast_to_primitive());}; 
    template<class T=T1, class U=T2> 
    struct primitive_div_t {using type=decltype(std::declval<T>()/std::declval<U>());}; 

    using T_res = typename std::conditional_t<std::is_fundamental<T1>{} && std::is_fundamental<T2>{}, primitive_div_t<>, cast_to_primitive_t<>>::type; 
};