Question: ```
//a class template to do something to STL container
template<typename T/*should be a STL container*/,typename Ele/*the type of element*/>
struct foo{
T a_container_with_an_element(){
    T con;
    Ele e;
    con.push_back(++++e);
    return con;
}

```

As you can see, it's really foolish to put the element's type into templates' parameter because it's already contained in the container's type.

So, is there any magic to get the element's type out of T?

Lots of Thx :-)

Answer: 
If the container is a standard library container, the name of the element is an embedded name of the container as follows:

```
typedef typename T::value_type type;

```

The standard container's have a few standard names in them (for example, see [vector on cppreference](http://en.cppreference.com/w/cpp/container/vector)) and the [C++ standard](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf) §23.2.

```
X::value_type
X::reference
X::const_reference
X::iterator
X::const_iterator
X::difference_type
X::size_type

```
In your special case where you know that T is a STL container Naill's answer is correct, use the nested types in the container.

If however you want a more generic "I know I am getting a template as T and I want the type of the first parameter of that template" case you can get the type through template specialization:

```
template<typename T>
struct MyFirstElement;
template<template<typename...> class T_Container, typename T_Type, typename... Ts>
struct MyFirstElement<T_Container<T_Type,Ts...>>{
    using Type = T_Type;
};

//unit test
using MustBeInt = typename MyFirstElement<std::vector<int>>::Type;
using MustBeLong = typename MyFirstElement<std::map<long,float>>::Type;

static_assert(std::is_same<MustBeInt,int>::value,"");
static_assert(std::is_same<MustBeLong,long>::value,""); 

//this works too even though its not an STL container
template<typename T, typename U, typename Z>
struct MyCrazyContainer{};

static_assert(std::is_same<typename MyFirstElement<MyCrazyContainer<bool,long,float>>::Type,bool>::value,"");

```

here is a live example: <http://ideone.com/OxhSOc>

As Jarod42 pointed out this will only work with templates which are "regular" i.e. only have types as parameters. std::array for example breatks this because it has an int as a second parameter.