6

このエラーで立ち往生しています。私も回避策を見つけましたが、それは運動の目的全体を殺してしまいます.

同じ container を指す 2 つの反復子を取る関数を作成しようとしています。それらの間の要素の合計を見つけます。正常に動作する vector のような順次コンテナ用の一般的な関数を作成しました。連想コンテナーに対して同じ関数をオーバーロードしました。これはエラーを与えるものです。

map<string,double> myMap;
myMap["B"]=1.0;
myMap["C"]=2.0;
myMap["S"]=3.0;
myMap["G"]=4.0;
myMap["P"]=5.0;

map<string,double>::const_iterator iter1=myMap.begin();
map<string,double>::const_iterator iter2=myMap.end();

cout<<"\nSum of map using the iterator specified range is: "<<Sum(iter1,iter2)<<"\n"; 
//Above line giving error. Intellisense is saying: Sum, Error: no instance of overloaded function "Sum" matches the argument list.

//function to calculate the sum is listed below (It appears in a header file with <map> header included):
template <typename T1,typename T2>
double Sum(const typename std::map<T1,T2>::const_iterator& input_begin,const typename std::map<T1,T2>::const_iterator& input_end)
{
double finalSum=0;
typename std::map<T1,T2>::const_iterator iter=input_begin;

for(iter; iter!=input_end; ++iter)
{
    finalSum=finalSum+ (iter)->second;
}

return finalSum;
}

コンパイル エラー: 1>c:\documents and settings\ABC\my documents\visual studio 2010\projects\demo.cpp(41): エラー C2783: 'double Sum(const std::map::const_iterator &,const std ::map::const_iterator &)': 'T1' のテンプレート引数を推測できませんでした

回避策:

call Sum(iter1,iter2) を Sum < string,double > (iter1,iter2) に置き換えると、正常にコンパイルされます。

そもそも、C++ 標準では不可能なことをしようとしていたのでしょうか。

4

1 に答える 1

7

次のテンプレートでは、エラーは実際には非常に明確です。

template <typename T1,typename T2>
double Sum(const typename std::map<T1,T2>::const_iterator& input_begin,
           const typename std::map<T1,T2>::const_iterator& input_end)

タイプT1T2は、呼び出しの場所で引数から推測できません。これは標準でそのように定義されており、(一般的なケースで)考えてみれば理にかなっています。

std::map<>::const_iteratorあなたが持っていたのではなくsometemplate<T>::nested_type、電話の場所での議論がint. コンパイラが型を推測しなければならない場合、宇宙 (無限集合) でsometemplate可能なすべての型をインスタンス化し、それらのどれがネストされた型が typedef であるかを見つける必要があります。Tnested_typeint

誰かがコメントで指摘しているように、テンプレートを変更して、マップのキーと値の型でテンプレート化する代わりに、イテレータだけを使用することができます。


値の抽出の委任

Sumこれは、シーケンシャル コンテナーと連想コンテナーの両方を処理できるの単一の実装を提供するための回避策です。

namespace detail {
template <typename T> T valueOf( T const & t ) { return t; }
template <typename K, typename V>
V valueOf( std::pair<const K, V> const & p ) {
   return p.second;
}
}
template <typename Iterator>
double Sum( Iterator begin, Iterator end ) {
  double result = 0;
  for (; begin != end; ++begin) {
     result += detail::valueOf(*begin);
  }
  return result;
}

私はコードをテストしていませんが、それでうまくいくはずです。Sumこれはおそらく、テンプレートで SFINAE を使用するよりもはるかに簡単です。

于 2012-11-26T21:30:00.340 に答える