2

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

假设我们有枚举:

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 中,位于 cp/pt.c:4414

起初我认为这可能是编译器错误,因为这些天可变参数模板仍然是新的。但是,这个错误报告线程似乎表明,虽然错误消息不是很有帮助,但 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;
};

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

4

1 回答 1

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;
};
于 2013-09-08T19:01:36.767 回答