Usar alias de plantilla sobre plantilla
Leyendo un libro Un recorrido por c ++ (segunda edición), 2018 , no entendí una explicación sobre las plantillas (lo explicaré a continuación).
Se dan dos firmas de función para una find_all
función que devuelve una vector
de iterator
sa todas las apariciones de un valor dado en un valor dado 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) ;
Ambos se pueden usar así:
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
Se dice que la plantilla de alias # 2 que usa
ocultar el detalle de la implementación introduciendo un alias de tipo para Iterator
por el autor.
Aunque creo que entiendo ambos usos de las plantillas, no entiendo por qué el número 2 "ocultaría los detalles de implementación" y por qué es preferible ... ¿Alguien puede explicarme?
Gracias !
postscriptum : No proporcioné a la publicación la definición de las funciones (lo mismo para ambas firmas) porque creo que no es útil, pero la agregaré si alguien la necesita.
Respuestas
Digamos que tienes una base de código como
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 decide que desea cambiar para devolver un vector de en const_iterator
lugar de iterator
, deberá cambiar todas esas funciones. Cuando usas
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);
todo lo que tendrías que hacer es cambiar
template<typename T>
using Iterator = typename T::iterator;
a
template<typename T>
using Iterator = typename T::const_iterator;
y tu estas listo. Así es como "oculta el detalle de la implementación".