我正在实现一个编译时过滤器,它基本上只需要一个枚举的编译时向量(一个可变参数包),对其进行迭代并尝试查找某个枚举是否包含在向量中。
假设我们有枚举:
enum Color
{
red,
green,
purple,
blue,
pink,
yellow
};
还有一个结构excluded_enums
,它只是我们要排除的枚举的编译时向量:
template <Color... ExcludedValues>
struct exclude_enums
{ };
然后我们可以有一个元函数: is_excluded
,它简单地返回true
或false
取决于枚举是否在 之中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;
};
但这失败并出现同样的错误。那么,这是编译器错误吗?如果不是,我如何编写一个终止模板递归的正确基本案例?