3

我正在使用 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,但微软不喜欢它。

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:“类型”:不是“std::enable_if”的成员

我将不胜感激有关如何完成这项工作的任何建议。

4

2 回答 2

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); }
于 2013-10-24T00:56:57.323 回答
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 会接受。

活生生的例子

于 2013-10-24T05:49:30.157 回答