2

I'm trying to define a template function that takes a container, which is also a template type. I need to know what the template type of the container is (E) (so I can refer to it in the code, e.g. E element = *iterator;). Here's my attempt:

template <template <typename E> T>
void sort(T& container){ ... }

I think this means "sort is a template function that takes a template argument T. T is a template type that takes a template argument E".

However I get the error:

expected 'class' before T.

When I put 'class' there, it says:

variable or field 'sort' declared void

What am I doing wrong with the syntax?

user3150201
  • 1,901
  • 5
  • 26
  • 29
  • 1
    Just take a plain type parameter `T` and then use `typename T::value_type`. What you are doing won't work with standard containers - they have more than one template parameter. – T.C. Oct 12 '14 at 14:10
  • 3
    `T` isn't a type. You can't have a reference to something that isn't a type. By the way, Clang [handles both errors very well](http://coliru.stacked-crooked.com/a/8dfca2ea54604829). – chris Oct 12 '14 at 14:11
  • 1
    As chris alludes to, you really also have to give the template `T` the proper arguments. Actually, you are not interested in a template, but a specific template-instantiation (a class). – Deduplicator Oct 12 '14 at 14:14
  • Gotta ask why not do this with iterators in the first place. If you really want a container version, write a forwarder template (and I'll warn you ahead of time, the standard containers have more parameters than you may first think). – WhozCraig Oct 12 '14 at 14:15

1 Answers1

1

There are other ways to achieve the same function. What you need is a template template parameter. A working example is:

template <typename E, template <typename> class T>
void sort(T<E>& container){}
main(){}

In the template signature, T is declared to be a (dependent) type that takes another type parameter. That parameter itself (E) needs to be declared and supplied to T, just as you would use in vector<int>.

You could also use:

    template <typename E, template <typename, typename...> class T>

if your container type expects optional parameters such as traits.

thor
  • 21,418
  • 31
  • 87
  • 173