2014-10-29 97 views
0
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

+0

哪个版本的C++是这样的? – matsjoyce 2014-10-29 14:19:47

+0

Visual Studio 2013 – SmallChess 2014-10-29 14:20:05

+0

无法推导出返回类型“T”。你想'双'或'std :: iterator_traits :: value_type' – Jarod42 2014-10-29 14:20:47

回答

4

返回类型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完成计算,无论该值是否适合容器类型。

3

返回类型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{}); 
}