I donβt think there is a clean way to do this if the non-type arguments do not have the same type, and you know what type it is. In this particular case, you can use function overloading.
In any other case, you get into the argument version of the ideal forwarding template, where you will need to specialize in each combination of type / nettype arguments.
If you only need to give uniform arguments without a pattern, and you can guess the type, then the following should work. You can overload instance_of for different types (only int is considered here), but you will need to explicitly create an instance for each type that you want to process:
// variation for non-type parameters, only for uniform parameters with // known type. template <typename V, template <V...> class C, typename T> struct check_is_instance_of_nontype : std::false_type { }; template <typename V, template <V...> class C, V... Values> struct check_is_instance_of_nontype<V, C, C<Values...>> : std::true_type { }; // this is as in your example template <template <typename...> class C, typename T> struct check_is_instance_of : std::false_type { }; template <template <typename...> class C, typename ...Ts> struct check_is_instance_of<C, C<Ts...>> : std::true_type { }; template <template <typename...> class C, typename T> struct is_instance_of : check_is_instance_of<C, std::remove_cv_t<T>> { }; template <template <typename...> class C, typename T> constexpr bool instance_of() { return is_instance_of< C, T>::value; } template <template <int...> class C, typename T> constexpr bool instance_of() { return check_is_instance_of_nontype< int, C, T>::value; } template< int... > struct Duck { }; template<typename A, typename B> struct Swallow { }; int main() { typedef Duck<1, 2> SittingDuck; typedef Swallow< int, int> UnladenSwallow; std::cout << instance_of< Duck, SittingDuck>() << instance_of< Swallow, UnladenSwallow>(); return 0; }
dhavenith
source share