2016-11-08 50 views
1

如何在不使用任意typedefs的情況下獲得此效果?類別模板參數的限制範圍

#include <type_traits> 
#include <iostream> 

typedef int Primary; 
typedef float Secondary; 

template<Class C, std::enable_if<std::is_same<Class, Primary>::value || std::is_same<Class, Secondary>::value> = 0> 
class Entity { 
public: 
    template<std::enable_if<std::is_same<Class, Secondary>::value>::type = 0> 
    void onlyLegalForSecondaryEntities() { 
     std::cout << "Works" << std::endl; 
    } 
}; 

int main() { 
    Entity<Secondary> e; 
    e.onlyLegalForSecondaryEntities(); 
    return 0; 
} 

有沒有產生這種使Entity只能PrimarySecondary作爲模板參數進行實例化一個更優雅的方式?

回答

3

在你的代碼修復錯誤後:

在C++ 1Z您可以輕鬆地滾特質is_anystd::disjunction

template<typename T, typename... Others> 
struct is_any : std::disjunction<std::is_same<T, Others>...> 
{ 
}; 

在C++ 11,可以實現disjuncation

template<class...> struct disjunction : std::false_type { }; 
template<class B1> struct disjunction<B1> : B1 { }; 
template<class B1, class... Bn> 
struct disjunction<B1, Bn...> 
    : std::conditional<B1::value != false, B1, disjunction<Bn...>>::type { }; 

然後定義你的類模板作爲

template<class C, typename std::enable_if<is_any<C, Primary, Secondary>::value>::type* = nullptr> 
class Entity { 
public: 
    template<typename std::enable_if<std::is_same<C, Secondary>::value>::type* = nullptr> 
    void onlyLegalForSecondaryEntities() { 
     std::cout << "Works" << std::endl; 
    } 
}; 

demo

您可以藉此進一步做出enable_if_any別名如果可能的話,將解析爲void

template<typename This, typename... Elems> 
using enable_if_is_any = typename std::enable_if<is_any<This, Elems...>::value>::type; 

template<class C, enable_if_is_any<C, Primary, Secondary>* = nullptr> 
class Entity { 
public: 
    template<typename std::enable_if<std::is_same<C, Secondary>::value>::type* = nullptr> 
    void onlyLegalForSecondaryEntities() { 
     std::cout << "Works" << std::endl; 
    } 
}; 

demo