Специализация шаблона с нетипичными аргументами variadi c - PullRequest
0 голосов
/ 22 января 2020

Я пытаюсь определить, относится ли тип к типу A (с какими-либо параметрами шаблона). Я использую вспомогательную структуру и шаблонную специализацию для него. Я сделал следующее:

#include <iostream>

template<typename,typename,typename,typename,int... pars> struct A{};

template<typename T> struct check: std::false_type{} ;

template<typename... T>
struct check<A<T...>> : std::true_type{}; // specialization is not applied

template<typename... T, int... pars>
struct check<A<T...,pars...>> : std::true_type{}; // same

// the following would get applied for any A:

// template<typename T1, typename T2, typename T3, typename T4, int... pars> 
// struct check<A<T1,T2,T3,T4,pars...>> : std::true_type{};

int main(){
    std::cout << check<A<int,char,double,int,1,2,3>>::value << std::endl;
}

Однако он выведет 0, поэтому некомментированные специализации не применяются. Это не должно работать или я что-то здесь упускаю? Существует ли аналогичный или альтернативный способ обнаружения для любого типа A, без необходимости записывать все typename T1 et c для класса A, как в приведенной выше строке с комментариями?

1 Ответ

0 голосов
/ 22 января 2020

Даже если наш человеческий мозг может определить пакет параметров рядом с пакетом параметров не-типов, компилятор не хочет пытаться выяснить, где заканчивается один пакет параметров, а начинается другой.

В общем, просто не очень хороший способ смешать переменное число аргументов типа и типа. Общий обходной путь заключается в том, что если вы можете изменить A, чтобы преобразовать не типовые аргументы в типы:

template <int... pars>
using make_pars = std::integer_sequence<int, pars...>;

А затем проверка будет намного проще

template <typename... Ts>
struct check : std::false_type {};

template <typename... Ts>
struct check<A<Ts...>> : std::true_type {};

И при использовании не так много дополнительного шаблона:

std::cout << check<A<int,char,double,int,make_pars<1,2,3>>>::value << std::endl;

Демонстрация: https://godbolt.org/z/7pMp2e

...