1

[リストまたはベクトル]の開始および終了イテレータを引数として受け入れるSum関数をオーバーロードしようとしています。このコンパイラエラーは本当に私を混乱させます。関連するコードは次のとおりです。

template <typename T1, typename T2>
const double Sum(const typename T1::const_iterator& start_iter, const typename T2::const_iterator& end_iter)
{// overloaded function that calculates sum between two iterators
    typename T1::const_iterator iterator_begin = start_iter;
    typename T2::const_iterator iterator_end = end_iter;

    double my_sum = 0;

    for (iterator_begin; iterator_begin != iterator_end; iterator_begin++)
        my_sum += *iterator_begin;

    return my_sum;      
}

int main()
{

list<double> test_list(10,5.1);
cout << Sum(test_list.begin(), test_list.end()); // compiler errors here

}

次のコンパイラエラーが発生します。

iterators.cpp(72):エラーC2783:'const double Sum(const T1 :: const_iterator&、const T2 :: const_iterator&)':'T1'のテンプレート引数を推測できませんでした

iterators.cpp(72):エラーC2783:'const double Sum(const T1 :: const_iterator&、const T2 :: const_iterator&)':'T2'のテンプレート引数を推測できませんでした

iterators.cpp(72):エラーC2780:'const double Sum(const std :: map&)':1つの引数が必要-2が提供されます

iterators.cpp(72):エラーC2780:'const double Sum(const T&)':1つの引数が必要-2が提供されます

コンパイラは、2つの入力でSum関数を呼び出そうとしていることをどのように認識しませんか?関数を間違って呼び出していますか?

ありがとう!

4

3 に答える 3

5

T1イテレータはいくつかのタイプのメンバーである必要があることを伝える必要はありませんT2。イテレータタイプ自体でテンプレート化するだけです。

template <typename Iter>
const double Sum(Iter iterator_begin, Iter iterator_end)
{
    double my_sum = 0;
    for (; iterator_begin != iterator_end; ++iterator_end)
        my_sum += *iterator_begin;
    return my_sum;      
}

int main()
{
    std::list<double> test_list;
    std::cout << Sum(test_list.begin(), test_list.end());
    return 0;
}

また、これを行う標準のstd::accumulateがあります。

int main()
{
    std::list<double> test_list;
    std::cout << std::accumulate(test_list.begin(), test_list.end(), 0.0);
    return 0;
}
于 2012-10-01T07:12:33.253 に答える
4

まず、あなたがこれをしたいとは思わない。すべてのシーケンスに基礎となるコンテナがあるわけではありません。istream_iterator(たとえば、sを考えてみてください。)さらに重要なことは、さまざまなコンテナーからのイテレーターの開始と終了を明確に許可(および奨励)していることです。とが異なるタイプのこの関数を合法的に使用できる場合はありません。テンプレートには単一のパラメーターが必要であり、これはイテレーターである必要があります。慣例により、イテレータの制約は、パラメータの名前で表す必要があります。たとえば、 (ここでは)、などです。T1T2InputIteratorForwardIterator

コードがコンパイルされない理由について:

ほとんどの場合、Pを構成するために使用される型、テンプレート、および非型の値は、テンプレート引数の推定に関与します。つまり、テンプレート引数の値を決定するために使用でき、そのように決定された値は、他の場所で決定された値と一致している必要があります。ただし、特定のコンテキストでは、値は型の推定に関与せず、代わりに、他の場所で推定された、または明示的に指定されたテンプレート引数の値を使用します。テンプレートパラメータが推定されないコンテキストでのみ使用され、明示的に指定されていない場合、テンプレート引数の推定は失敗します。

推定されないコンテキストは次のとおりです。

—修飾IDを使用して指定されたタイプのネストされた名前指定子。

[...]

(§14.8.2.5/ 4,5から。)

于 2012-10-01T07:38:14.893 に答える
2

このようなメソッドを呼び出します。

Sum<list<double>,list<double> >(test_list.begin(), test_list.begin());
于 2012-10-01T07:06:13.947 に答える