Utilizzo dell'alias del modello sul modello

Jan 09 2021

Leggendo un libro A tour of c ++ (seconda edizione), 2018 , non ho capito una spiegazione sui modelli (spiegherò di seguito).

Vengono fornite due firme di funzione per una find_allfunzione che restituisce a vectordi iterators a tutte le occorrenze di un dato valore in un dato 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) ;

Entrambi possono essere usati in questo modo:

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

Si dice che il modello di alias # 2 utilizzi

nascondere i dettagli dell'implementazione introducendo un alias di tipo per Iterator

dall'autore.

Anche se penso di capire entrambi gli usi dei modelli, non capisco perché # 2 dovrebbe "nascondere i dettagli di implementazione" e perché è preferito ... Qualcuno può spiegarmi?

Grazie !

postscriptum : non ho fornito al post la definizione delle funzioni (uguale per entrambe le firme) perché penso che non sia utile, ma la aggiungerò se qualcuno ne ha bisogno.

Risposte

6 NathanOliver Jan 09 2021 at 05:54

Diciamo che hai una base di codice come

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);
...

Se decidi di voler modificare per restituire un vettore const_iteratorinvece di iterator, dovrai modificare tutte quelle funzioni. Quando si usa

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);

tutto quello che dovresti fare è cambiare

template<typename T>
using Iterator = typename T::iterator;

per

template<typename T>
using Iterator = typename T::const_iterator;

e hai finito. Ecco come "nasconde i dettagli di implementazione".