Usar alias de plantilla sobre plantilla

Jan 09 2021

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_allfunción que devuelve una vectorde iteratorsa 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

6 NathanOliver Jan 09 2021 at 05:54

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