我遇到了这个错误。 我也找到了一种解决方法,但它有点扼杀了锻炼的全部目的。
我正在尝试创建一个函数,它将指向同一个容器的两个迭代器。我会找到它们之间的元素总和。我创建了像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 ++标准做一些不可能的事情?
答案 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)
T1
和T2
类型不能从通话地点的参数中推断出来。这在标准中是这样定义的,如果你考虑它(在一般情况下)它是有道理的。
考虑一下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简单得多。