Unified and Atypical Template Type Parameters

I have a type that checks if this type is an instance of this class template:

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

Unfortunately, this does not work for non-piggy type template parameters, since they are not "captured" by the variation template parameters, therefore

 is_instance_of<std::integral_constant, std::true_type> 

gives a compilation error. Is there a way to write an implementation of is_instance_of that works for an arbitrary number of type parameters and a non-piggy template?

+7
c ++ template-meta-programming
source share
1 answer

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; } 
+1
source share

All Articles