En bref: Parce que l'utilisation d'un modèle de paramètre du modèle est plus restrictive* que l'utilisation d'un paramètre de type sans fournir d'avantages.
* Par "restrictif", je veux dire que vous devrez peut-être des trucs plus complexe à obtenir les mêmes résultats qu'avec un "simple" paramètre de type.
Pourquoi il n'y a pas d'avantages?
Votre std::stack
a probablement un attribut comme ceci:
template <typename T, typename Container>
struct stack {
Container container;
};
Si vous remplacez Container
, par un modèle de paramètre du modèle, pourquoi voulez-vous obtenir?
template <typename T, template <typename...> class Container>
struct stack {
Container<T> container;
};
Vous êtes l'instanciation Container
qu'une seule fois et uniquement pour T
(Container<T>
), donc il n'y a aucun avantage pour un modèle de paramètre du modèle.
Pourquoi est-il plus restrictive?
Avec un modèle de paramètre du modèle, vous devez passer à l' std::stack
un modèle qui exposent la même signature, par ex.:
template <typename T, template <typename> class Container>
struct stack;
stack<int, std::vector> // Error: std::vector takes two template arguments
Peut-être que vous pourriez utiliser variadic templates:
template <typename T, template <typename....> class Container>
struct stack {
Container<T> container;
};
stack<int, std::vector> // Ok, will use std::vector<int, std::allocator<int>>
Mais que faire si je ne veux pas utiliser la norme std::allocator<int>
?
template <typename T,
template <typename....> class Container = std::vector,
typename Allocator = std::allocator<T>>
struct stack {
Container<T, Allocator> container;
};
stack<int, std::vector, MyAllocator> // Ok...
Cela devient un peu brouillon... Que faire si je veux utiliser mon propre conteneur des modèles qui prend les 3/4/N paramètres?
template <typename T,
template <typename... > class Container = std::vector,
typename ...Args>
struct stack {
Container<T, Args...> container;
};
stack<int, MyTemplate, MyParam1, MyParam2> // Ok...
Mais, que faire si je veux utiliser un non-basé sur un modèle de conteneur?
struct foo { };
struct foo_container{ };
stack<foo, foo_container> // Error!
template <typename... >
using foo_container_template = foo_container;
stack<foo, foo_container_template> // Ok...
Avec un paramètre de type, il n'y a pas de telles questions1:
stack<int>
stack<int, std::vector<int, MyAllocator<int>>
stack<int, MyTemplate<int, MyParam1, MyParam2>>
stack<foo, foo_container>
1 Il y a d'autres cas qui ne fonctionne pas avec le modèle modèle de paramètre, par exemple à l'aide de modèles acceptant un mélange du type et de la non-paramètres de type de commandes spécifiques, pour lesquels vous pouvez créer de modèle générique de paramètre du modèle, même à l'aide de variadic templates.