18

I want to know if it is at all possible to have code that has the following behaviour:

int main()
{
    func<vector>(/*some arguments*/);
}

That is, I want the user to be able to specify the container without specifying the type that it operates on.

For example, some (meta) code (which does not work with the above) that might define func would be as follows:

template<typename ContainerType>
int func(/*some parameters*/)
{
    ContainerType<int> some_container;
    /*
        operate on some_container here
    */
    return find_value(some_container);
}
Konrad
  • 2,207
  • 4
  • 20
  • 31
  • 6
    Well, you already have the answer in the question title... – Kerrek SB Jul 05 '16 at 10:22
  • @dasblinkenlight: That's eminently possible. You need a template template parameter, exactly as the OP says in the question. – Kerrek SB Jul 05 '16 at 10:27
  • Note that while template template parameters exist, they're rarely the right way to parameterize things. It's usually much better to parametrize on the type, and extract features of the types via traits. – Kerrek SB Jul 05 '16 at 10:28
  • @KerrekSB I did try various template template parameters, but it seems like Jarod42 gave me the right version (I nearly got it right) :) – Konrad Jul 05 '16 at 10:28
  • 1
    Related: [c++ template class; function with arbitrary container type, how to define it?](http://stackoverflow.com/questions/7728478/c-template-class-function-with-arbitrary-container-type-how-to-define-it) – iammilind Jul 05 '16 at 10:39
  • I am not sure if you really need a `vector` or if this is a contrived example. If you are looking at doing this with a container class, consider using a pair of iterators instead. The C++ algorithms library has plenty of examples of how to do this. –  Jul 05 '16 at 15:01

2 Answers2

22

The syntax is

template <template <typename...> class ContainerType>
int func(/*some parameters*/)
{
    // Your code with ContainerType<int>
}

Note: class cannot be replaced by typename (until c++17).

You cannot simply use typename instead of typename... Because std::vector takes Type and Allocator (defaulted): std::vector<T, Allocator>

Jarod42
  • 203,559
  • 14
  • 181
  • 302
9

Try this:

template<template<typename,typename> class ContainerType>
int func (/*some parameters*/)
{

}

You need two inner template parameters since std::vector is defined as:

template < class T, class Alloc = allocator<T> > class vector;

Mattia F.
  • 1,720
  • 11
  • 21