2015-04-25 13 views
0

我有一個模板類看起來像這樣:禁用功能,當參數類型爲void

template <typename T> constexpr bool is_value_passable_v = is_trivially_copyable_v<T> && sizeof(T) <= sizeof(void*) && !is_polymorphic_v<T>; 
template <typename B, typename T> using param_base_t = conditional_t<is_value_passable_v<B>, T, const T&>; 

template <typename T> struct param_d 
{ 
    using type = param_base_t<T, T>; 
}; 

template <> struct param_d<void> 
{ 
    using type = void; 
}; 

template <typename T> using param_t = typename param_d<T>::type; 

template <class TIn> class CClass 
{ 
    public: 
     static constexpr bool use_input_v = !is_same_v<typename TIn::input_t, void>; 
     using input_t = conditional_t<use_input_v, param_t<typename TIn::input_t>, void>; 

     enable_if_t<use_input_v> Input(input_t i); 
}; 

這段代碼的目標是,到provde不同Input功能不同的模板paramters。

  • input_t = int模板參數應導致void Input(int i)
  • input_t = std::vector模板參數應導致void Input(const std::vector& i)
  • input_t = void模板參數應該刪除Input功能

鏗鏘編譯此給出

/usr/bin/../include/c++/v1/type_traits:225:78: error: no type named 'type' in 'std::__1::enable_if<false, void>'; 'enable_if' cannot be used to disable this declaration 
template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type; 
                      ^~~ 

編輯1: 添加行

template <typename T> static constexpr bool use_input2_v = use_input_v; 

template <typename T = void> enable_if_t<use_input2_v<T>> Input(input_t i) 

鐺替換函數聲明之後抱怨有no matching member function for call to 'Input'

note: candidate template ignored: substitution failure [with T = void]: non-type template argument is not a constant expression 
template <typename T = void> enable_if_t<use_input2_v<T>> Input(input_t i); 
             ~~~~~~~~~~~~ ^

編輯2: 忘了提及,這個錯誤伴隨着模板參數的所有三種變體。

編輯3: 樣本使用情況CClass可能是

class CInput0 
{ 
    using input_t = int; 
}; 

class CInput1 
{ 
    using input_t = std::vector<int>; 
}; 

class CInput2 
{ 
    using input_t = void; 
}; 

CClass<CInput0> in0; 
CClass<CInput1> in1; 
CClass<CInput2> in2; 

std::vector<int> i = {1, 2, 3}; 

in0.Input(3); 
in1.Input(i); 
//in2.Input() disabled 
+0

爲什麼你不只是使用'static constexpr bool use_input_v =!is_same ;'? – MikeMB

+0

而不是use_input2_v版本? Afaik enable_if只能根據'直接'模板禁用函數。 – Uroc327

+0

'template constexpr bool is_value_passable_v = is_trivially_copyable_v && sizeof(T)<= sizeof(void *)&&!is_polymorphic_v ;'這是什麼?它既不是功能也不是班級模板。 – Lingxi

回答

1

對於SFINAE`to工作,它需要工作一個依賴類型,否則沒有替代失敗。這裏有一個例子:

template <typename Self = CClass<TIn>> 
    typename std::enable_if<Self::use_input_v>::type 
     Input(typename Self::input_t) { } 

當一個成員函數是一個模板,基於模板參數是否正常工作的編譯器有條件地創建它。在你最初的例子中,由於整個類是一個模板,但是該方法不是,只要類實例化,編譯器就會認爲它是成員函數的錯誤。使用默認的模板參數就是我們需要的技巧。我們想測試的東西現在被認爲是相關的。

0

如果要啓用基於模板參數的屬性功能,沒有局部特殊化,你可以使用下面的模式:

#include <iostream> 
#include <type_traits> 
#include <vector> 

std::ostream& operator<<(std::ostream& out, std::vector<int>& value); 

template <class TIn> class CClass 
{ 
    public:   
     template <class T =TIn, class PARAM= std::enable_if_t<!(std::is_same<void,typename T::input_t>::value) ,typename T::input_t > > 
     void Input(PARAM i){ 
      std::cout << "Called Input with parameter: "<< i << std::endl; 
     } 
}; 

struct CInput0{ using input_t = int;}; 
struct CInput1{ using input_t = std::vector<int>;}; 
struct CInput2{ using input_t = void;}; 

CClass<CInput0> in0; 
CClass<CInput1> in1; 
CClass<CInput2> in2; 

std::vector<int> i = {1, 2, 3}; 
std::ostream& operator<<(std::ostream& out, std::vector<int>& value) { 
    for (auto& e:value) { 
     out << e; 
    } 
    out << std::endl; 
    return out; 
} 

int main() { 

    in0.Input(3); 
    in1.Input(i); 
    //in2.Input() disabled 
} 

這是您的示例的簡化版本,您應該可以對其進行修改。

相關問題