Verwenden des Vorlagenalias über der Vorlage
Ein Buch lesen Eine Tour durch C ++ (zweite Ausgabe), 2018 , ich habe keine Erklärung zu Vorlagen verstanden (ich werde es unten erklären).
Für eine find_all
Funktion, die a vector
von iterator
s für alle Vorkommen eines bestimmten Werts in einem bestimmten Wert zurückgibt, werden zwei Funktionssignaturen angegeben 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) ;
Beide können folgendermaßen verwendet werden:
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
Die # 2 mit Alias-Vorlage soll
Blenden Sie die Implementierungsdetails aus, indem Sie einen Typalias für Iterator einführen
vom Autor.
Obwohl ich denke, dass ich beide Verwendungszwecke von Vorlagen verstehe, verstehe ich nicht, warum # 2 "das Implementierungsdetail verbergen" sollte und warum es bevorzugt wird ... Kann mich jemand erklären?
Vielen Dank !
postscriptum : Ich habe dem Post nicht die Definition der Funktionen gegeben (für beide Signaturen gleich), weil ich denke, dass es nicht nützlich ist, aber ich werde es hinzufügen, wenn jemand es braucht.
Antworten
Nehmen wir an, Sie haben eine Codebasis wie
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);
...
Wenn Sie entscheiden, dass Sie ändern möchten, um einen Vektor const_iterator
anstelle von zurückzugeben iterator
, müssen Sie alle diese Funktionen ändern. Beim Benutzen
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);
Alles was Sie tun müssten, ist sich zu ändern
template<typename T>
using Iterator = typename T::iterator;
zu
template<typename T>
using Iterator = typename T::const_iterator;
und du bist fertig. So "verbirgt es das Implementierungsdetail".