テンプレートよりもテンプレートエイリアスを使用する

Jan 09 2021

本を読むc ++のツアー(第2版)、2018年、テンプレートについての説明がわかりませんでした(以下で説明します)。

二つの関数シグネチャがために与えられるfind_all返す関数vectoriterator所与で与えられた値のすべてのオカレンスに秒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が「実装の詳細を非表示にする」理由とそれが好まれる理由がわかりません...誰か説明してもらえますか?

ありがとう!

postscriptum:役に立たないと思うので、関数の定義(両方の署名で同じ)を投稿に提供しませんでしたが、誰かがそれを必要とする場合は追加します。

回答

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;

これで完了です。これが「実装の詳細を隠す」方法です。