#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>();
}