La méthode C++ consiste à utiliser des itérateurs. Tout comme toutes les fonctions <algorithm>
qui prennent (it begin, it end,)
comme deux premiers paramètres.
template <class IT>
T foo(IT first, IT last)
{
return std::accumulate(first, last, T());
}
Si vous voulez vraiment passer le conteneur lui-même à la fonction, vous devez utiliser les paramètres 'template template'. Cela est dû au fait que les conteneurs de bibliothèque standard C++ sont non seulement modélisés avec le type du type contenu, mais aussi avec un type d'allocateur, qui ont une valeur par défaut et sont donc implicites et non connus.
#include <vector>
#include <list>
#include <numeric>
#include <iostream>
template <class T, class A, template <class T, class A> class CONT>
T foo(CONT<T, A> &cont)
{
return std::accumulate(cont.begin(), cont.end(), T());
}
int main()
{
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
std::list<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
std::cout << foo(v) << " " << foo(l) << "\n";
return 0;
}
Aussi, il est assez rare qu'il soit utile de prendre un conteneur génériquement. Les seules fonctions membres d'un conteneur sont begin, end, size, max_size, empty et swap. Si vous avez les itérateurs début/fin, vous pouvez faire tout cela sauf max_size (qui est presque inutile) et swap, bien que la taille puisse être beaucoup plus lente avec les itérateurs. Les conteneurs ont aussi différents types, dont la plupart peuvent être obtenus à partir des itérateurs de l'itérateur. Donc, en prenant n'importe quel conteneur sauve surtout la frappe. Être un peu plus spécifique (prendre une séquence, par exemple) pourrait être plus utile. –