How do I get the type of the elements in a vector?

You can get the type like this:

typename std::vector<T>::value_type;

Then use static_assert together with std::is_same.

template <typename T1, typename T2>
void special_push_back(std::vector<T1>& v, T2 elem)
{
  // check that T1 and T2 are the same before pushing elem into v
}

then

std::vector<int> v;
special_push_back(v, 3.14); // Compile time error: double is not int

If you have C++11 features, you can also use decltype keyword to ease the access to underlying value_type type member:

decltype(TheContainer)::value_type nVarOfType;

Here, TheContainer might be a container of any type. For instance, a map<int, string>, deque<float> or any other STL container - all STL containers have value_type type-defined. decltype key would give the type of given object.


If I understood the comments correctly, you may also try:

template <class Container, class... Args>
void foo(Container&& c, Args&&... args) {
    typedef typename Container::value_type value_type;

    // use type_traits to check value_type
    ...
}

An improvement would be to check whether Container has an embedded type value_type at all:

template <class T>
struct has_value_type
{
private:
    template <class U> static std::false_type test(...);
    template <class U> static std::true_type test(typename U::value_type*);
public:
    enum { value = decltype(test<T>(0))::value };
};

and then use std::enable_if:

template <class Container, class... Args>
typename std::enable_if<has_value_type<Container>::value, return_type>::type 
foo(Container&& c, Args&&... args) {
    typedef typename Container::value_type value_type;
    ...
}

Similarly, you can "enable" only templates which fulfill your requirement of the value type:

template <class Container, class... Args>
typename std::enable_if<
    has_value_type<Container>::value
    and std::is_same<int, typename Container::value_type>::value
>::type
foo2(Container&& c, Args&&... args) {
    typedef typename Container::value_type value_type;

    // here value_type equals int
}

Edit:

With even more "template tricks", you can for example ensure that all types of the variadic template pack are equal and and equals the value_type of the container:

First, a helper template:

template <typename...>
struct all_of;

template <typename T>
struct all_of<T> : std::conditional<T::value == true,
    std::true_type, std::false_type>::type
{};

template <typename Head, typename... Tail>
struct all_of<Head, Tail...> : std::conditional<
    Head::value == true and all_of<Tail...>::value,
    std::true_type,
    std::false_type>::type
{};

Without any further code, you can use it already, for example as follows:

`all_of<std::is_nothrow_copy_constructible<Args>...>::value`

While the syntax may appear weird, the const expression above evaluates to true if all types in the parameter pack Args have the property that its copy-constructor will not throw.

Given the helper class template all_of, we can now enable the function template foo only if all types in the parameter pack equal the value_type of the container:

template <class Container, class... Args>
typename std::enable_if<
    has_value_type<Container>::value
    and all_of<std::is_same<typename Container::value_type, Args>...>::value
>::type
foo2(Container&& c, Args&&... args) {
    typedef typename Container::value_type value_type;

    // here *all* types in Args are equal value_type
}