Как развернуть шаблон Variadic в условии? - PullRequest
0 голосов
/ 20 июня 2019

Я хочу развернуть шаблон переменной в отдельные функции, используемые в сочетании с 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)) Есть ли способ, которым я могу это сделать? Или есть дополнительный адаптер, который я могу использовать для этого?

Живой пример

Ответы [ 3 ]

2 голосов
/ 20 июня 2019

Если ваш компилятор поддерживает C ++ 17 складчатые выражения , вам нужно изменить две вещи, чтобы он работал:

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

Живой пример

1 голос
/ 21 июня 2019

Так что в печальном случае, что мой не [поддержка выражений сгиба] ... Могу я что-нибудь сделать?

Что ж, если это действительно так, и проблема была не только в забывании обязательных скобок , то вы можете пойти по пути, который нужно было обрабатывать с помощью шаблонов с переменными параметрами до 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";
    }
}
1 голос
/ 20 июня 2019

Вам нужна дополнительная пара круглых скобок

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

Очевидно, если ваш компилятор поддерживает C ++ 17 (свертывание шаблонов).

Может быть более понятным, как показано ниже

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