Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using template alias over template

Reading a book A tour of c++ (second edition), 2018, I didn't understand an explanation about templates (I'll explain below).

Two function signatures are given for a find_all function that returns a vector of iterators to all occurrences of a given value in a given 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) ;

Both can be used like this :

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

The #2 using alias template is said to

hide the implementation detail by introducing a type alias for Iterator

by the author.

Although I think I understand both usage of templates, I don't understand why would #2 "hide the implementation detail" and why it is preferred ... Can anyone explain me ?

Thanks !

postscriptum : I didn't provide the post with the definition of the functions (same for both signatures) because I think it isn't useful, but I'll add it if anyone needs it.

like image 660
limserhane Avatar asked Jan 08 '21 22:01

limserhane


Video Answer


1 Answers

Lets say you have a code base like

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

If you decide you want to change to return a vector of const_iterator instead of iterator, you'd need to change all of those functions. When using

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

all you would have to do is change

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

to

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

and you're done. This is how it "hides the implementation detail".

like image 164
NathanOliver Avatar answered Oct 23 '22 15:10

NathanOliver