3

入力がそのコンテナの 2 つの const_iterator である、特定のコンテナで最も一般的な要素を見つける関数を作成しました (以下のコードを参照)。ただし、この関数をfindMostFrequent(ivec.begin(), ivec.end())where ivecis avector<int>で呼び出すと、コンパイラはテンプレート引数を推測できません。で関数を呼び出すとfindMostFrequent< vector<int> >(ivec.begin(), ivec.end())問題なく動作しますが、面倒なようです。インスタンス化するテンプレートをコンパイラに見つけさせる方法はありますか?

template <typename T> typename T::value_type findMostFrequent(typename T::const_iterator beg, typename T::const_iterator end)
{
    // T is the type of container, T::value_type is the type which is stored in the container
    typename T::size_type current_streak = 0, max_streak = 0;
    T::value_type max_so_far;
    for (T::const_iterator iter = beg; iter != end; ++iter)
    {
        current_streak = count(beg, end, *iter);
        if ( current_streak > max_streak )
        {
            max_so_far = *iter;
            max_streak = current_streak;
        }
    }
    return max_so_far;
}
4

3 に答える 3

10

コンパイラーはネストされた指定子を推測できません。「パラメーターとして表示される型と等しいネストされた指定子を持つ型を見つけてください」は複雑すぎて、簡単に解決できないことがよくあります。代わりに、イテレータから知る必要のあるすべてのものを直接推測してみてください。

template <typename IteratorType>
typename std::iterator_traits<IteratorType>::value_type
findMostFrequent(IteratorType beg, IteratorType end)
{
    typename std::iterator_traits<T>::difference_type current_streak = 0, max_streak = 0;
    typename std::iterator_traits<T>::value_type max_so_far;
    for (IteratorType  iter = beg; iter != end; ++iter)
    {
        current_streak = count(beg, end, *iter);
        if ( current_streak > max_streak )
        {
            max_so_far = *iter;
            max_streak = current_streak;
        }
    }
    return max_so_far;
}

std::iterator_traits<T>::value_type代わりに使用する必要がある理由T::value_typeは、ポインターなど、自然に定義されない型に対してもこれらの「イテレーター仕様」を使用できるようにするためです。たとえば、は実際にはこのスニペットの有効なイテレータですが、 typedef/typeT*は含まれていません。value_type

于 2012-07-17T08:34:08.677 に答える
3

はい、関数にIterテンプレート引数を受け入れさせ、Tイテレータ特性(<iterator>)を使用してそれから推測することにより、基本的にその逆になります。

于 2012-07-17T08:31:01.717 に答える
2

テンプレート パラメーターとして反復子型を使用する必要があるためです。以下のコードはうまくいきます

#include <iostream>
#include <vector>

template <typename IterType> 
typename IterType::value_type findMostFrequent(IterType beg, IterType end)
{
    // T is the type of container, T::value_type is the type which is stored in the container
    unsigned int current_streak = 0, max_streak = 0;
    typename IterType::value_type max_so_far;
    for (IterType iter = beg; iter != end; ++iter)
    {
        current_streak = count(beg, end, *iter);
        if ( current_streak > max_streak )
        {
            max_so_far = *iter;
            max_streak = current_streak;
        }
    }
    return max_so_far;
}

int main()
{
    std::vector<int> v;
    for (unsigned int i = 0; i < 10; ++i)
        v.push_back(i);

    findMostFrequent(v.begin(), v.end());

    return 0;
}

あなたのコードでは、反復子の型は vector と関係がなく、その結果、コンパイラはテンプレート パラメーターを推測できませんでした

于 2012-07-17T08:37:46.793 に答える