我试图创建一个函数来对 std::vector
的所有元素求和:
template<typename IteratorT>
auto sum(IteratorT first, IteratorT last) -> decltype(*first) {
decltype(*first) sum = 0;
for (; first != last; ++first)
sum += *first;
return sum;
}
我得到了这个错误:
cannot convert from 'int' to 'int&'
经过一些研究,我发现了这个:std::iterator_traits<IteratorT>::difference_type
.将我的代码更改为:
template<typename IteratorT>
auto sum(IteratorT first, IteratorT last) -> typename std::iterator_traits<IteratorT>::difference_type {
std::iterator_traits<IteratorT>::difference_type sum = 0;
for (; first != last; ++first)
sum += *first;
return sum;
}
它确实有效,但我不确定为什么以及它是否是一个好的解决方案。最后我有两个问题:
1) 为什么 decltype(*first)
返回 int&
而不是 int
正如我所料
2)到底是什么typename
之前std::iterator_traits<IteratorT>::difference_type
做和为什么sum
如果我删除它,功能将不起作用
最佳答案
主要有两个问题:
解引用迭代器的类型是引用,它可以是
const
,对于std::vector
,它可能与 vector 的非常不同项目类型。当项目类型是例如
bool
,您不想在bool
类型中求和。
下面的代码是一种解决方案:
#include <iterator> // std::iterator_traits
template< class Iter >
auto sum( Iter first, Iter last )
-> decltype( typename std::iterator_traits<Iter>::value_type() + 0 )
{
decltype( typename std::iterator_traits<Iter>::value_type() + 0 ) sum = 0;
for (; first != last; ++first)
sum += *first;
return sum;
}
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
#define ITEMS( x ) begin( x ), end( x )
auto main()
-> int
{
vector<double> const v1 = {3, 1, 4, 1, 5};
cout << sum( ITEMS(v1) ) << endl;
vector<bool> const v2 = {0, 1, 1, 0, 1};
cout << sum( ITEMS( v2) ) << endl;
}
请注意,您不必定义自己的sum
:有std::accumulate
。
关于C++ 类型的解引用迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38514449/