简体   繁体   中英

How Do I Unroll a Variadic Template in a Condition?

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

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

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) && ...) )

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM