Verwenden des Vorlagenalias über der Vorlage

Jan 09 2021

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_allFunktion, die a vectorvon iterators 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

6 NathanOliver Jan 09 2021 at 05:54

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_iteratoranstelle 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".