错误C2783无法推断模板参数

时间:2012-11-26 21:19:01

标签: c++ templates

我遇到了这个错误。 我也找到了一种解决方法,但它有点扼杀了锻炼的全部目的。

我正在尝试创建一个函数,它将指向同一个容器的两个迭代器。我会找到它们之间的元素总和。我创建了像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&gt; c:\ documents and settings \ ABC \ my documents \ visual studio 2010 \ projects \ demo.cpp(41):error C2783:'double Sum(const std :: map :: const_iterator&amp;,const std :: map :: const_iterator&amp;)':无法推断'T1'的模板参数

解决方法:

如果调用Sum(iter1,iter2)替换为Sum&lt; string,double&gt; (iter1,iter2),它编译得很好。

我是否首先尝试按照C ++标准做一些不可能的事情?

1 个答案:

答案 0 :(得分:6)

错误实际上非常清楚,在以下模板中:

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。如果编译器必须推断出类型,则必须为Universe中的所有可能类型sometemplate实例化T(无限集),并找到嵌套类型nested_type中的哪一个是int typedef到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

我没有测试过代码,但是应该这样做。这可能比在{{1}}模板上使用SFINAE简单得多。