Search code examples
c++classtemplatescontainerstypename

c++: why template cannot be used to deduce both container and element type?


I've got a very simple test program like below:

#include<vector>
#include<iostream>
using namespace std;
template<typename C, typename E>
void f(const C<E>& container){
    cout<<container.size()<<endl;
}
int main(){
    vector<int> i;
    f(i);
    return 0;
}

It fails to compile with gcc 4.1.2. Error message is:

templateContainer.cpp:5: error: ‘C’ is not a template
templateContainer.cpp: In function ‘int main()’:
templateContainer.cpp:10: error: no matching function for call to ‘f(std::vector<int, std::allocator<int> >&)’

Solution

  • You could use a template template parameter (and note that std::vector actually takes more than one template parameter [an element type, and an allocator type]).:

    template<template <typename...> class C, typename... E>
    void f(const C<E...>& container){
        cout<<container.size()<<endl;
    }
    

    Live Demo


    If you don't need the type decompositions, you could simply use an ordinary template.

    template<typename C>
    void f(const C& container){
        cout<<container.size()<<endl;
    }
    

    You can additionally obtain typedefs from STL containers: for example, if you want to know the type of elements held by the container, value_type is there for you.

    template<typename C>
    void f(const C& container){
        using ValueType = typename C::value_type;
        cout<<container.size()<<endl;
    }