template <class Iter, class T> T sum(Iter first, Iter last)
{
return std::accumulate(first, last, 0.0);
}
// Not compiled...
const double b = sum(v.begin(), v.end());
// Compiled
const double b = sum<std::vector<double>::const_iterator, double>(v.begin(), v.end());
我想编写一个通用模板函数来计算容器的总和。我想在不指定模板参数的情况下实现这一目标。在我的尝试中,我必须定义两个丑陋的参数。如何编写干净的代码?如果编译器无法完成这项工作,则该函数将毫无意义。
使用 Visual Studio 2013
类型T
无法从迭代器类型推断出来。
在 C++14 中,您可以从返回值推断出它
template <class Iter> auto sum(Iter first, Iter last)
在 C++11 中,您可以从迭代器类型中获取它
template <class Iter> auto sum(Iter first, Iter last) -> decltype(*first)
或来自特征
template <class Iter>
typename std::iterator_traits<Iter>::value_type
sum(Iter first, Iter last)
从历史上看,这会很尴尬。您可以将其设置为第一个参数,以便可以推断出第二个参数
template <class T, class Iter> T sum(Iter first, Iter last)
const double b = sum<double>(v.begin(), v.end());
或者添加一个额外的函数参数来指定初始值;但这样你的函数将与std::accumulate
本身相同。
应使用 T()
而不是 0.0
作为初始值,否则将使用double
是否适合容器类型进行计算。
无法推断返回类型 T。
以下可能会有所帮助:
template <class Iter>
typename std::iterator_traits<Iter>::value_type sum(Iter first, Iter last)
{
return std::accumulate(first, last, typename std::iterator_traits<Iter>::value_type{});
}