Utilisation d'un alias de modèle sur un modèle
Lecture d'un livre A tour of c ++ (deuxième édition), 2018 , je n'ai pas compris une explication sur les templates (je l'expliquerai ci-dessous).
Deux signatures de fonction sont données pour une find_all
fonction qui renvoie a vector
de iterator
s à toutes les occurrences d'une valeur donnée dans une donnée container
.
#1 :
template<typename C, typename V>
vector<typename C::iterator> find_all(C& c, V v);
# 2:
template<typename T>
using Iterator = typename T::iterator;
template<typename C, typename V>
vector<Iterator<C>> find_all(C& c, V v) ;
Les deux peuvent être utilisés comme ceci:
string m {"Mary had a little lamb"};
for (auto p : find_all(m,'a')) // here p is a string::iterator
cout << *p << endl; // spoiler alert : this will print 'a's
On dit que le modèle d'alias n ° 2 utilise
masquer le détail de l'implémentation en introduisant un alias de type pour Iterator
par l'auteur.
Bien que je pense comprendre à la fois l'utilisation des modèles, je ne comprends pas pourquoi # 2 "cacherait le détail de l'implémentation" et pourquoi il est préférable ... Quelqu'un peut-il m'expliquer?
Merci !
postscriptum : Je n'ai pas fourni à l'article la définition des fonctions (idem pour les deux signatures) car je pense que ce n'est pas utile, mais je l'ajouterai si quelqu'un en a besoin.
Réponses
Disons que vous avez une base de code comme
template<typename C, typename V>
vector<typename C::iterator> first(C& c, V v);
template<typename C, typename V>
vector<typename C::iterator> second(C& c, V v);
template<typename C, typename V>
vector<typename C::iterator> third(C& c, V v);
template<typename C, typename V>
vector<typename C::iterator> fourth(C& c, V v);
...
Si vous décidez de changer pour renvoyer un vecteur de const_iterator
au lieu de iterator
, vous devrez changer toutes ces fonctions. Lors de l'utilisation
template<typename T>
using Iterator = typename T::iterator;
template<typename C, typename V>
vector<Iterator<C>> first(C& c, V v);
template<typename C, typename V>
vector<Iterator<C>> second(C& c, V v);
template<typename C, typename V>
vector<Iterator<C>> third(C& c, V v);
template<typename C, typename V>
vector<Iterator<C>> fourth(C& c, V v);
tout ce que tu aurais à faire est de changer
template<typename T>
using Iterator = typename T::iterator;
à
template<typename T>
using Iterator = typename T::const_iterator;
et tu as fini. C'est ainsi qu'il «cache le détail de l'implémentation».