为可变参数模板编写基础案例

时间:2013-09-08 18:49:00

标签: c++ c++11 variadic-templates

我正在实现一个编译时过滤器,它基本上只需要Enums的编译时向量(一个可变参数包),迭代它并尝试查找向量中是否包含某个枚举。

假设我们有枚举:

enum Color
{
  red,
  green,
  purple,
  blue,
  pink,
  yellow
};

结构excluded_enums,它只是我们想要排除的枚举的编译时向量:

template <Color... ExcludedValues>
struct exclude_enums
{ };

我们可以有一个元函数:is_excluded,只需返回truefalse,具体取决于枚举是否属于ExcludedValues

通过可变参数包进行编译时线性搜索的实际实现看起来非常简单:

template <Color Test, Color Head, Color... Tail>
struct is_excluded_impl
{ 
  static const bool value = (Test == Head ? true : is_excluded_impl<
    Test, Tail...>::value);
};

template <Color Test, Color... Tail>
struct is_excluded_impl<Test, Tail...> 
{ 
   static const bool value = false;
};

问题是编译器(GCC 4.7)不喜欢我的基本情况。它失败了:

  

内部编译器错误:在process_partial_specialization中,at   CP / pt.c:4414

起初我认为这可能是编译器错误,因为可变参数模板现在仍然是新的。但是,this bug report thread似乎表明,虽然错误消息不是很有用,但GCC拒绝这一点是正确的,因为部分特化并不比主模板更专业,因为它用包扩展替换了多个参数。

好的,所以我试图通过包含额外的“count”参数来强制它认为基本情况更加专业化,这是可变参数包中剩下的参数数量:

template <std::size_t NumArgs, Color Test, Color Head, Color... Tail>
struct is_excluded_impl
{ 
  static const bool value = (Test == Head ? true : is_excluded_impl<sizeof...(Tail), Test, 
    Tail...>::value);
};

template <Color Test, Color... Tail>
struct is_excluded_impl<0, Test, Tail...> 
{ 
   static const bool value = false;
};

但是失败并出现同样的错误。那么,这是一个编译错误吗?如果没有,我如何编写一个终止模板递归的正确基础案例?

1 个答案:

答案 0 :(得分:3)

使用单个可变参数包声明主模板:

template <Color...>
struct is_excluded_impl : std::false_type {};

template <Color Test, Color Head, Color... Tail>
struct is_excluded_impl<Test, Head, Tail...>
{
    static const bool value =
        Head == Test || is_excluded_impl<Test, Tail...>::value;
};