我正在实现一个编译时过滤器,它基本上只需要Enums的编译时向量(一个可变参数包),迭代它并尝试查找向量中是否包含某个枚举。
假设我们有枚举:
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中,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;
};
但是失败并出现同样的错误。那么,这是一个编译错误吗?如果没有,我如何编写一个终止模板递归的正确基础案例?
答案 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;
};