Utilisation d'un alias de modèle sur un modèle

Jan 09 2021

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_allfonction qui renvoie a vectorde iterators à 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

6 NathanOliver Jan 09 2021 at 05:54

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_iteratorau 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».