The std container inside the template

Hey.

I don’t know very well how to explain myself, but I believe that part of the code will make you understand what I'm going to do:

template<class A, class B> void myFunction(A<B>& list) { typename A<B>::iterator current = list.begin(); typename A<B>::iterator end = list.end(); while (current != end) { current++; } } 

Where A is the STL container (vector, list ...). This is similar to the beginning, but with templates: template, inside template, etc.

The thing is, what do you do when one of the parameters of your template is itself a template ... and still wants to support all types supported by this template.

This, of course, does not compile (it says "A is not a template").

Does anyone know how to create such a template?

+6
c ++ std templates containers
source share
3 answers

You are looking for a template template option

 template<template<class T, class All = std::allocator<T> > class A, class B> void myFunction(A<B>& list) { typename A<B>::iterator current = list.begin(); typename A<B>::iterator end = list.end(); while (current != end) { current++; } } 

However, in your particular case, I think it would be better for you just to pass the intensified container, i.e.

 template<class C> void myFunction(C& list) { ... } 

use

 vector<char> v; myFunction(v); 

Your source code should be called as follows:

 myFunction<std::vector, char> (v) 

which is much more detailed and not of much use.

+7
source share

A and B will be specific types (not patterns), so A<B> does not make sense.

You can write your code as follows:

 template<class List> void myFunction(List &list) { typename List::iterator current = list.begin(); typename List::iterator end = list.end(); while (current != end) { current++; } } 

If you need to know what is the type of an element of this list, there is a typedef for it:

 typename List::value_type 
+2
source share

Good to solve this little problem. It is pretty simple. vector<int> is a class, so you do not need to declare A<B> in the prototype. You can simply do this:

 template<class A> void myFunction(A& list) { typedef typename A::value_type B; //do this if you need to know the type of the elements. typename A::iterator current = list.begin(); typename A::iterator end = list.end(); while (current != end) { current++; } } 

But if you really need to, you can also declare the template argument as a template:

 template< template<class> class A, class B > void myFunction(A<B>& list) { typename A<B>::iterator current = list.begin(); typename A<B>::iterator end = list.end(); while (current != end) { current++; } } 

But this is not recommended, and most class templates have a set of nested typedefs (such as iterator and value_type in STL containers), so you can get all the necessary information about the type without using this template template parameters. Thus, the first method is usually the preferred and more normal way to execute it (usually there are also fewer problems to make it work, that is, the Compiler tends to “dislike” template template parameters).

In addition, you cannot easily use STL containers with template template parameters, since STL containers have all of these “hidden” template arguments (for example, “dispenser” and “compare” for sorted containers). Thus, you will also need to list all of this, otherwise the compiler will not be able to complete the match. And then you will not have a very “general" function, because you will have to think so much about the STL container that passed because it will only serve one or two types of containers. It is better to use the first method.

-one
source share

All Articles