Usando o alias do modelo sobre o modelo
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_all
função que retorna a vector
de iterator
s 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
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_iterator
vez 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".