0

I'm looking to unroll a variadic template into separate functions used in the conjunction of an if-statement. Here's an example of what I'm trying to do:

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";
    }
}

But this gives me the error:

error C3520: ARGS: parameter pack must be expanded in this context

I want the line: if(bar<ARGS>(param) && ...) to unroll to: if(bar<0U>(param) && bar<1U>(param) && bar<2U>(param)) Is there a way I can do this? Or is there an additional adapter that I can use which will accomplish this?

Live Example

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288

3 Answers3

2

If your compiler supports C++17's fold-expressions you need to change two things to make it work:

1.Change the order of template parameters in bar so that T can be deduced when I in explicitly specified:

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

2.Add a pair of parentheses inside if since they are a mandatory part of a fold-expression:

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

Live Example

r3mus n0x
  • 5,954
  • 1
  • 13
  • 34
1

You need an additional couple of parentheses

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

Obviously if your compiler support C++17 (template folding).

Maybe clearer as follows

if( true == (bar<ARGS>(param) && ...) )
max66
  • 65,235
  • 10
  • 71
  • 111
1

So in the sad event that mine does not [support fold expressions] ... Can I do anything?

Well, if that's really the case and the issue was not solely for forgetting the required parentheses, then you can go the way variadic templates needed to be handled before 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";
    }
}
Aconcagua
  • 24,880
  • 4
  • 34
  • 59