Использование псевдонима шаблона поверх шаблона

Jan 09 2021

Читая книгу Экскурсия по c ++ (второе издание), 2018 , я не понял объяснения о шаблонах (объясню ниже).

Две сигнатуры функции даны для find_allфункции, которая возвращает a vectorof iterators для всех вхождений данного значения в данное 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) ;

Оба могут использоваться следующим образом:

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

# 2, использующий шаблон псевдонима, называется

скрыть детали реализации, введя псевдоним типа для Iterator

автор.

Хотя я думаю, что понимаю оба использования шаблонов, я не понимаю, почему №2 «скрывает детали реализации» и почему это предпочтительнее ... Кто-нибудь может мне объяснить?

Спасибо !

постскриптум : я не предоставил пост с определением функций (одинаковым для обеих подписей), потому что я думаю, что это бесполезно, но я добавлю его, если кому-то это понадобится.

Ответы

6 NathanOliver Jan 09 2021 at 05:54

Допустим, у вас есть кодовая база вроде

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

Если вы решите, что хотите изменить, чтобы вернуть вектор const_iteratorвместо вместо iterator, вам нужно будет изменить все эти функции. Когда используешь

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

все, что вам нужно сделать, это изменить

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

к

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

и вы сделали. Вот так он «скрывает детали реализации».