Let\'s say I have two structs, Foo
and Bar
:
template
struct Foo{};
template
struct Bar{};
Here is a general C++14 solution that does not rely on manually specialized type traits or extending Foo
and Bar
.
A template metafunction that obtains a type representing the class template of its argument type:
namespace detail
{
// Type representing a class template taking any number of non-type template arguments.
template class U>
struct nontype_template {};
}
// If T is an instantiation of a class template U taking non-type template arguments,
// this has a nested typedef "type" that is a detail::nontype_template representing U.
template
struct nontype_template_of {};
// Partial specializations for all of the builtin integral types.
template class T, bool... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, char... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, signed char... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, unsigned char... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, short... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, unsigned short... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, int... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, unsigned int... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, long... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, unsigned long... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, long long... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
template class T, unsigned long long... Vs>
struct nontype_template_of> { using type = detail::nontype_template; };
An alias template for ease of use:
// Alias template for nontype_template_of.
template
using nontype_template_of_t = typename nontype_template_of::type;
Then you can implement your match_class
trait just like this:
template
struct match_class : std::is_same, nontype_template_of_t> {};
DEMO