有没有办法在C ++模板专业化中将条件置于常量值参数?

时间:2017-05-25 22:16:52

标签: c++ templates

有没有办法将整数模板参数限制为专门化而不是代码冗余?

// redundant code

template <int N>
struct A {};
template <>
struct A <0> {};
template <>
struct A <1> {};

// what i want is some thing like this

template <int N>
struct A {};

template <>
struct A <N < 2> {};

2 个答案:

答案 0 :(得分:5)

您可以使用SFINAE =“替换失败不是错误”。这有几种方法可以在这里完成,例如

template<int N, typename E=void>
struct A { /* ... */ };     // general type

template<int N>
struct A<N, std::enable_if_t<(N<2)> >
{ /* ... */ };              // specialisation for N<2

请注意std::enable_if_t<>是C ++ 14类型,它等同于

template<bool C, typename T=void>
using enable_if_t = typename std::enable_if<C,T>::type;

它是如何运作的? std::enable_if的定义类似于

template<bool C, typename T=void>
struct enable_if { using type=T; };

template<typename T>
struct enable_if<false,T> {};

特别是,如果条件enable_if::type为false,则不存在子类型C。因此,在上述专业化中,enable_if_t<(N<2)>仅针对void扩展为有效类型(N<2)。对于N>=2,我们有替换失败,因为enable_if<(N<2)>::type不存在。 C ++允许这样的失败,但只是忽略了生成的(无效的)代码。

答案 1 :(得分:2)

您可以添加第二个模板参数,其默认值选择所需的专业化:

template <int N, bool = (N < 2)>
struct A {
    // code for N>=2 case
};

template <int N>
struct A<N, true> {
    // code for N<2 case
};

(您不需要为第二个参数命名,因为您永远不会明确指出它。)