我正在学习 STL 和模板。这是我的问题。我写了这个函数来计算两个迭代器“之间”的元素总和:
template <typename Iter> double PartialSum(Iter itBegin, Iter itEnd){
if (itBegin == itEnd) return 0.;
double dSum = 0;
while(itBegin != itEnd){
dSum += (*itBegin);
++itBegin;
}
return dSum;
}
这很好用(我知道我可以使用 std::accumulate
但这是为了学习目的)。现在,我想为 std:map
提供相同的功能,但那里的迭代器与 std::vector
和 std::list 的工作方式不同
。因此,我想编写重载/专用的 PartialSum
。我尝试但失败的是这个(最小示例):
template <typename T1, typename T2> double PartialSum(std::map<T1,T2>::iterator itBegin{
return 0.;
}
这是错误日志:
Main.cpp(42): error: nontype "std::map<_Key, _Tp, _Compare, _Alloc>::iterator [with _Key=T1, _Tp=T2, _Compare=std::less<T1>, _Alloc=std::allocator<std::pair<const T1, T2>>]" is not a type name template <typename T1, typename T2> double PartialSum(std::map<T1,T2>::iterator itBegin){ Main.cpp(83): error: no instance of overloaded function "PartialSum" matches the argument list argument types are: (std::_Rb_tree_iterator<std::pair<const std::string, int>>) std::cout<<"Map partial sum: "<<PartialSum(myMap.begin())<<std::endl;
由于它是如此简单,我可能没有理解一些非常基本的东西。很高兴听到您的意见:-)
最佳答案
尝试用另一种方式表述。
考虑你有功能
template<typename T>
T f(){
return T();
}
这里不可能自动得到T,所以你需要把它命名为f<T>()
.同样
template <typename T>
int f(typename type<T>::inner){
//
}
例如,如果你有
struct type{
typedef int inner;
}
这里很容易看出,如果你调用f(0)
不可能得到T。
你可能会说在那种特殊情况下可以用 map
得到它,但您将如何定义它?
您应该阅读 c++ 标准以了解哪种类型应该是可推导的。
在你的情况下,你可以通过以下方式调用
PartialSum<std::string, int>(m.begin());
顺便说一句,似乎 map 只是一种不常见的情况,您可以尝试做一些更通用的事情,这将适用于任何迭代器类型。你可能会看到 std::accumulate
来源以获得一些想法。
template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
inline _Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
_BinaryOperation __binary_op)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__init = __binary_op(__init, *__first);
return __init;
}
关于具有STL容器的c++函数模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16064838/