I couldn't come up with a way to define one generic metafunction that does it, but here is a possible workaround:
#include <iostream>
#include <type_traits>
using namespace std;
// PRIMARY TEMPLATE
template<typename T>
class something
{
};
// SPECIALIZATIONS FOR int
template<typename T, int... U, template<typename, int...> class L>
class something<L<T, U...>>
{
public:
typedef int type;
};
template<typename T, template<typename, int...> class L>
class something<L<T>>
{
public:
typedef size_t type;
};
// SPECIALIZATIONS FOR unsigned int
template<typename T, unsigned int... U, template<typename, unsigned int...> class L>
class something<L<T, U...>>
{
public:
typedef unsigned int type;
};
template<typename T, template<typename, unsigned int...> class L>
class something<L<T>>
{
public:
typedef size_t type;
};
/* ... OTHER SPECIALIZATIONS ... */
struct A {};
struct B {};
int main()
{
static_assert(is_same<something<MyClass1<A, 1, 2>>::type, int>::value, "Error!");
static_assert(is_same<something<MyClass1<A>>::type, size_t>::value, "Error!");
static_assert(is_same<something<MyClass2<B, 1U, 2U, 3U>>::type, unsigned int>::value, "Error!");
static_assert(is_same<something<MyClass2<B>>::type, size_t>::value, "Error!");
return 0;
}
I tried to write only single specialization that would cover all cases, like this:
template<typename U, typename T, U... V, template<typename, U...> class L>
class something<L<T, V...>>
{
public:
typedef U type;
};
But Clang 3.2 complains that the type of U cannot be deduced, so this specialization of get_type
will never be used. So if you follow this approach you will have to explicitly define each specialization. This may or may not be acceptable depending on your use cases. Hope it helps.