如何匹配模板参数字符集

时间:2013-10-24 00:45:02

标签: c++ c++11

我正在使用Visual Studio 2013 RTM。

我正在尝试编写一个与多个字符之一匹配的可变参数模板。递归案例很容易,但我正在努力编写基本案例。

template <char C, char... Cs>
auto char_match(char c) -> bool
{
    return c == C || char_match<Cs...>(c);
}

我尝试了以下作为基本案例,但它没有用。我知道你可以用类模板做到这一点,我很确定你不能用功能模板来做。

template <>
auto char_match(char c) -> bool
{
    return false;
}

错误C2912:'bool char_match(char)'的显式特化不是函数模板的特化

我也尝试在返回类型上使用std :: enable_if,但Microsoft不喜欢它。

template <char C, char... Cs>
typename std::enable_if<sizeof...(Cs) != 0, bool>::type char_match(char c)
{
    return c == C || char_match<Cs...>(c);
}

template <char C, char... Cs>
typename std::enable_if<sizeof...(Cs) == 0, bool>::type char_match(char c)
{
    return c == C;
}

错误C2039:'type':不是'std :: enable_if'

的成员

我很感激有关如何使这项工作的任何建议。

2 个答案:

答案 0 :(得分:5)

没有任何关于“专业化”的更专业的而不是主模板,所以这不起作用。我认为最简单的解决方案是使用类模板:

template <char ...> struct char_match_impl;

template <> struct char_match_impl<>
{
    static bool go(char) { return false; }
};

template <char C, char ...Cs> struct char_match_impl<C, Cs...>
{
    static bool go(char c) { return c == C || char_match_impl<Cs...>::go(c); }
};

template <char ...Cs>
bool char_match(char c)
{ return char_match_impl<Cs...>::go(c); }

答案 1 :(得分:3)

在您的特定情况下,没有理由进行递归,只需使用

即可
template< char... Cs >
bool char_match( char c )
{
    constexpr const std::array< char, sizeof...( Cs ) > a {{ Cs... }};
    return std::find_if(std::begin(a), std::end(a),
                        [c](char x){return x==c;}) != std::end(a);
}

不确定VC ++是否会接受代码,但是GCC和Clang会这样做。

Live example