#include <type_traits>
template<typename T>
struct extract_value_type
{
typedef T value_type;
};
template<template<typename> class X, typename T>
struct extract_value_type <X<T>> //specialization
{
typedef T value_type;
};
/////////////////////////////
struct X {};
template <typename T> struct Y {};
template<typename C, typename T>
void test()
{
typedef typename extract_value_type<C>::value_type value_type;
static_assert(std::is_same<value_type, T>::value, "mismatched");
}
int main()
{
test<X,X>();
test<Y<X>,X>();
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IGV4dHJhY3RfdmFsdWVfdHlwZQp7CiAgICB0eXBlZGVmIFQgdmFsdWVfdHlwZTsKfTsKCnRlbXBsYXRlPHRlbXBsYXRlPHR5cGVuYW1lPiBjbGFzcyBYLCB0eXBlbmFtZSBUPgpzdHJ1Y3QgZXh0cmFjdF92YWx1ZV90eXBlIDxYPFQ+PiAgIC8vc3BlY2lhbGl6YXRpb24KewogICAgdHlwZWRlZiBUIHZhbHVlX3R5cGU7Cn07CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKc3RydWN0IFgge307CnRlbXBsYXRlIDx0eXBlbmFtZSBUPiBzdHJ1Y3QgWSB7fTsKCnRlbXBsYXRlPHR5cGVuYW1lIEMsIHR5cGVuYW1lIFQ+CnZvaWQgdGVzdCgpCnsKICAgdHlwZWRlZiB0eXBlbmFtZSBleHRyYWN0X3ZhbHVlX3R5cGU8Qz46OnZhbHVlX3R5cGUgdmFsdWVfdHlwZTsKICAgc3RhdGljX2Fzc2VydChzdGQ6OmlzX3NhbWU8dmFsdWVfdHlwZSwgVD46OnZhbHVlLCAibWlzbWF0Y2hlZCIpOwp9CgppbnQgbWFpbigpCnsKICAgdGVzdDxYLFg+KCk7CiAgIHRlc3Q8WTxYPixYPigpOwp9