3

たとえば、cplusplus.comのこのスニペットを参照すると、次のようになります。

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;
}
4

1 に答える 1

5

コメントで提案した提案-関数に別のテンプレート引数を持たせる-は、意図したとおりに機能しません。あなたが提案したコードは次のとおりです。

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、引数の型から型を推定することはできません (InputIteratorとのT型は 2 つの引数から推測できますが、シグネチャだけからはコンテキストがありません)。そのため、この呼び出しはコンパイラ エラーで失敗します。ここでの使用はstd::iterator_traits、反復子の型自体から反復子に関する情報を抽出するための一般的なテンプレート パターンです。

于 2016-11-21T16:34:28.793 に答える