限制类的模板参数范围

时间:2016-11-08 21:20:01

标签: c++11 templates sfinae

如果没有任意typedef,我怎么能有这个效果?

numFeatures (Phi(X) types): 245343 [CLASS, 2-SW-et, 2-SW-stop, 2-SW-somebody, 2-SW-organizating, ...]

是否有更优雅的方式来生成此类,以便#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; } 只能使用EntityPrimary作为模板参数进行实例化?

1 个答案:

答案 0 :(得分:3)

修复代码中的错误后:

在C ++ 1z中,您可以使用is_any轻松滚动特征std::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