Usando o alias do modelo sobre o modelo

Jan 09 2021

Lendo um livro Um tour por c ++ (segunda edição), 2018 , não entendi uma explicação sobre templates (explicarei abaixo).

Duas assinaturas de função são fornecidas para uma find_allfunção que retorna a vectorde iterators para todas as ocorrências de um determinado valor em um 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 podem ser usados ​​assim:

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

O nº 2 usando o modelo de alias é dito

ocultar os detalhes de implementação, introduzindo um alias de tipo para Iterator

pelo autor.

Embora eu ache que entendo o uso de modelos, não entendo por que o nº 2 "esconderia os detalhes de implementação" e por que ele é preferido ... Alguém pode me explicar?

Obrigado !

postscriptum : Não forneci ao post a definição das funções (o mesmo para ambas as assinaturas) porque acho que não é útil, mas vou adicioná-lo se alguém precisar.

Respostas

6 NathanOliver Jan 09 2021 at 05:54

Digamos que você tenha uma 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);
...

Se você decidir que deseja alterar para retornar um vetor de em const_iteratorvez de iterator, será necessário alterar todas essas funções. Ao usar

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);

tudo que você teria que fazer é mudar

template<typename T>
using Iterator = typename T::iterator;

para

template<typename T>
using Iterator = typename T::const_iterator;

e pronto. É assim que "esconde o detalhe da implementação".