2016-11-08 25 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が唯一のテンプレート引数としてPrimaryまたはSecondaryでインスタンス化することができるように、これを生成するために、よりエレガントな方法はありますか?

答えて

3

あなたのコード内のエラーを修正した後:あなたは簡単にstd::disjunctionとトレイトis_anyをロールバックすることができます1Z Cで

++:

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<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

:あなたはこれをさらに取ると、可能な場合 voidに解決されます enable_if_anyエイリアスを作ることができます
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