2016-11-21 2 views
3

cplusplus.comからこのスニペットには、例えば、参照:別のテンプレート型引数を使用するのではなく、テンプレート関数でiterator_traitsを使用するのはなぜですか?

template <class InputIterator, class T> 
typename iterator_traits<InputIterator>::difference_type 
count(InputIterator first, InputIterator last, const T& val) 
{ 
    typename iterator_traits<InputIterator>::difference_type ret = 0; 
    while (first!=last) { 
     if (*first == val) 
      ++ret; 
     ++first; 
    } 
    return ret; 
} 

疑問は、なぜ、むしろ別のテンプレート引数に取るよりも、この文脈でiterator_traitsを使用している、ここで示したように:

template <class InputIterator, class T, class DiffType> 
DiffType count(InputIterator first, InputIterator last, const T& val) 
{ 
    DiffType ret = 0; 
    while (first!=last) { 
     if (*first == val) 
      ++ret; 
     ++first; 
    } 
    return ret; 
} 
+3

かなり幅広いですが、イテレータの特性、実際には一般的な(メンバータイプのような)特性は適切な規則でうまくいきます。習慣によって「標準」特性を使うことで、アルゴリズムとデータ構造が標準のテンプレートライブラリとうまくやりとりされ、より良いメタプログラミングが可能になります。 – AndyG

+0

もう1つのテンプレートクラス*を定義することはできますが、一度やり直すと、1つの異なるアルゴリズムごとにもう一度やりたいとは思わないでしょう。 –

+0

私は密度が高いかもしれませんが、あなたが考えているものの例を与えることができますか?あなたの最後の文で? – Quentin

答えて

4

提案しますコメントで提案されている - 別のテンプレート引数を取る関数を持つ - はあなたが意図したとおりに動作しません。ここでは、提案されてきたコードは次のとおりです。

template <class InputIterator, class T, typename DiffType> 
DiffType count(InputIterator first, InputIterator last, const T& val) 
{ 
    DiffType ret = 0; 
    while (first!=last) { 
     if (*first == val) 
      ++ret; 
     ++first; 
    } 
    return ret; 
} 

このコードの問題は、これはもはやコンパイルされることである:

std::vector<int> v = /* ... */; 
auto numElems = count(v.begin(), v.end(), 137); // <--- Error! 

ここでの問題は、すべてのテンプレート引数、順番に関数テンプレートを呼び出すために、ということではありません引数型から推論可能であるか、呼び出し側によって明示的に指定されなければなりません。ここでは、タイプDiffTypeを引数タイプから推測することはできません(InputIteratorTタイプは2つの引数から推論できますが、シグネチャだけではコンテキストがありません)、この呼び出しはコンパイラエラーで失敗します。 std::iterator_traitsの使用は、イテレータのタイプ自体からイテレータに関する情報を抽出するための一般的なテンプレートパターンです。

+0

DiffTypeは、少なくとも最初のテンプレート引数である可能性があります。まだ全てが重視されているわけではありませんが、ちょっと良いと思います... – Deduplicator

+0

@BoPerssonよ、良い点。私はこれを修正しました。 – templatetypedef

+0

@Deduplicatorこの場合、差分タイプを明示的に指定する必要はありませんか? – templatetypedef

関連する問題