#include <type_traits>
#include <vector>
#include <set>
#include <list>
template<typename T>
struct extract_value_type
{
typedef T value_type;
};
template<template<typename, typename ...> class X, typename T, typename ...Args>
struct extract_value_type<X<T, Args...>> //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>();
test<std::vector<X>,X>();
test<std::set<X>,X>();
test<std::list<X>,X>();
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8bGlzdD4KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBleHRyYWN0X3ZhbHVlX3R5cGUKewogICAgdHlwZWRlZiBUIHZhbHVlX3R5cGU7Cn07Cgp0ZW1wbGF0ZTx0ZW1wbGF0ZTx0eXBlbmFtZSwgdHlwZW5hbWUgLi4uPiBjbGFzcyBYLCB0eXBlbmFtZSBULCB0eXBlbmFtZSAuLi5BcmdzPgpzdHJ1Y3QgZXh0cmFjdF92YWx1ZV90eXBlPFg8VCwgQXJncy4uLj4+ICAgLy9zcGVjaWFsaXphdGlvbgp7CiAgICB0eXBlZGVmIFQgdmFsdWVfdHlwZTsKfTsKCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgpzdHJ1Y3QgWCB7fTsKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBZIHt9OwoKdGVtcGxhdGU8dHlwZW5hbWUgQywgdHlwZW5hbWUgVD4Kdm9pZCB0ZXN0KCkKewogICB0eXBlZGVmIHR5cGVuYW1lIGV4dHJhY3RfdmFsdWVfdHlwZTxDPjo6dmFsdWVfdHlwZSB2YWx1ZV90eXBlOwogICBzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfc2FtZTx2YWx1ZV90eXBlLCBUPjo6dmFsdWUsICJtaXNtYXRjaGVkIik7Cn0KCmludCBtYWluKCkKewogICB0ZXN0PFgsWD4oKTsKICAgdGVzdDxZPFg+LFg+KCk7CiAgIHRlc3Q8c3RkOjp2ZWN0b3I8WD4sWD4oKTsKICAgdGVzdDxzdGQ6OnNldDxYPixYPigpOwogICB0ZXN0PHN0ZDo6bGlzdDxYPixYPigpOwp9