错误C2783无法推导模板参数

error C2783 Could not deduce template arguments

本文关键字:参数 C2783 错误      更新时间:2023-10-16

我遇到了这个错误我也找到了一个变通办法,但它有点扼杀了锻炼的全部目的

我正在尝试创建一个函数,该函数将使用两个指向同一容器的迭代器。我会找到它们之间元素的总和。我为顺序容器创建了通用函数,比如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"的模板参数

解决方法:

如果调用Sum(iter1,iter2)被Sum<string,double>(iter1,iter2),它编译得很好。

我是不是一开始就试图按照C++标准做一些不可能的事情?

在以下模板中,错误实际上非常明显:

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。如果编译器必须推导类型,它必须为宇宙(无限集)中所有可能的类型T实例化sometemplate,并找到嵌套类型nested_typeint的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模板上使用SFINAE简单得多。