简体   繁体   中英

Template specialization with variadic non-type arguments

I'm trying to detect if a type is of type A (with any template parameters). I'm using a helper struct and template specialization for it. I did the following:

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

However, it will print out 0, so the uncommented specializations are not applied. Is it not supposed to work or am I missing something here? Is there a similar or alternative way of detecting for any type A, without having to write out all the typename T1 etc for the class A as in the commented line above?

Even though our human brains can deduce a parameter pack of types next to a parameter pack of non-types, the compiler is not willing to try to figure out where one parameter pack ends, and another begins.

In general, there's just not a good way to mix a variable number of type and non-type arguments. The general workaround is, if you can modify A , to promote the non-type arguments to types:

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

And then, the check is much simpler

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

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

And there's not much extra boilerplate when using:

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

Demo: https://godbolt.org/z/7pMp2e

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