Utilizzo dell'alias del modello sul modello
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_all
funzione che restituisce a vector
di iterator
s 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
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_iterator
invece 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".