如何在条件下展开可变参数模板?

时间:2019-06-20 19:49:51

标签: c++ templates metaprogramming variadic-templates index-sequence

我正在寻求将可变参数模板展开为与if语句结合使用的单独函数。这是我要执行的操作的示例:

template <typename T, size_t I>
bool bar(const T& param) { return param[I] != 13; }

template <typename T, size_t... ARGS>
void bar(const T& param, const std::index_sequence<ARGS...>&) { 
    if(bar<ARGS>(param) && ...)
    {
        cout << "no matches\n";
    }
    else
    {
        cout << "matched\n";
    }
}

但这给了我错误:

  

错误C3520:ARGS:必须在这种情况下扩展参数包

我希望以下行:if(bar<ARGS>(param) && ...)展开至:if(bar<0U>(param) && bar<1U>(param) && bar<2U>(param))有没有办法做到这一点?还是有一个我可以使用的附加适配器来实现此目的?

Live Example

3 个答案:

答案 0 :(得分:2)

如果您的编译器支持C ++ 17的fold-expressions,则需要更改两项以使其正常工作:

1。更改bar中模板参数的顺序,以便在明确指定T时可以推论I

template <size_t I, typename T>
bool bar(const T& param) { return param[I] != 13; }

2。在if内添加一对括号,因为它们是折叠表达式的必需部分:

if ((bar<ARGS>(param) && ...))

Live Example

答案 1 :(得分:1)

您需要再加上几个括号

// .V.......................V
if( (bar<ARGS>(param) && ...) )

很明显,如果您的编译器支持C ++ 17(模板折叠)。

也许更清楚如下

if( true == (bar<ARGS>(param) && ...) )

答案 2 :(得分:1)

  

因此,在不幸的事件中,我的 [support fold expressions] ...我可以做什么?

好吧,如果确实是这样,并且问题不仅仅在于forgetting the required parentheses,那么您可以采用在C ++ 17之前需要处理可变参数模板的方式:

template < typename T >
bool bar(T const& param) { return true; }

template <typename T, size_t I, size_t ... II>
bool bar(T const& param) { return param[I] != 13 && bar<T, II...>(param); }

template <typename T, size_t... ARGS>
void bar(T const& param, std::index_sequence<ARGS...> const&)
{
    if(bar<T, ARGS...>(param))
    {
        std::cout << "no matches\n";
    }
    else
    {
        std::cout << "matched\n";
    }
}