2016-12-09 52 views
5

我有一個函數:C++ - 的std :: enable_if更多類型

template <typename T, 
    typename std::enable_if <std::is_same<T, int>::value == true>::type* = nullptr> 
void test(T i) 
{ 
    //process data 
} 

它的工作原理。

但是,我需要啓用此功能不僅爲int,但爲floatconst char *以及...如何做到這一點,而無需編寫相同的方法3倍?

回答

10

像這樣:

template <typename T, 
    typename std::enable_if <std::is_same<T, int   >::value || 
          std::is_same<T, float  >::value || 
          std::is_same<T, const char *>::value>::type* = nullptr> 
void test(T i) 
{ 
    //process data 
} 
+0

一個建議。如果限定符在重載的選擇中無關緊要,可能可以使用'remove_cv'。 –

+0

@YanZhou由於參數'i'不是通過引用傳遞的,而是通過值,常量和volatile將被移除。因此,'T'不會被cv限定,'remove_cv'不會對該類型做任何事情。 –

2

用於C++ 17.一種通用的解決方案(在godbolt.org選中)

#include <type_traits> 

template< typename U, typename ... Ts > struct belong_to 
{ 
    // before C++17 value will have to be defined recursively on the head of Ts 
    static constexpr bool value = (std::is_same< U, Ts >::value || ...); 
    using type = typename std::enable_if< value, U > ::type; 
}; 

// usage example: 
template< typename T > 
using testable = typename belong_to< T, int, float, const char >::type; 

template< typename T > void test (testable<T> i) 
{ 
    // test process 
} 

int main() 
{ 
    test< int  > (3); 
    test< float  > (3.0); 
    test< const char > ('c'); 
    // test< signed char >(1); does not compile!!! 
} 
1

另一個通用的解決方案是使用std ::析取(C++ 17)以執行邏輯或。允許的類型在調用測試函數時被指定爲模板參數,或者你可以爲專門化定義一個typedef。

#include <iostream> 
#include <type_traits> 

template <typename... Ts, typename T, typename std::enable_if<std::disjunction<std::is_same<T, Ts>...>::value>::type* = nullptr> 
void test(T i) 
{ 
    std::cout << "test\n"; 
} 

int main() 
{ 
    int i = 4; 
    test<int, float, const char*>(i); 
    //test<float, const char*>(i); // compile fails since no int 

    // or use a typedef for the specialization 
    typedef void (*specialized_t)(int); 
    constexpr specialized_t test2 = &test<int, float, const char*>; 
    test2(i); 
} 

run the code