C ++类型的解引用迭代器 [英] C++ type of dereferenced iterator
问题描述
我试图制作一个对std::vector
的所有元素求和的函数:
I tried to make a function that sums all elements of an 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;
}
我收到此错误:
无法从'int'转换为'int&'
cannot convert from 'int' to 'int&'
然后经过一番研究,我发现了这一点:std::iterator_traits<IteratorT>::difference_type
.将我的代码更改为:
Then after some research I found this: std::iterator_traits<IteratorT>::difference_type
. Changed my code to:
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;
}
它确实起作用了,但是我不确定为什么以及这是否是一个好的解决方案.最后,我有两个问题:
and it did work, but I am not sure why and if it's a good solution or not. In conclusion I have two questions:
1)为什么decltype(*first)
返回int&
而不是我期望的int
2)std::iterator_traits<IteratorT>::difference_type
之前的typename
究竟是什么?为什么删除了sum
功能后,为什么不起作用
1) Why decltype(*first)
returns int&
and not int
as I expected
2) What exactly typename
before std::iterator_traits<IteratorT>::difference_type
does and why sum
function doesn't work if I remove it
推荐答案
有两个主要问题:
-
取消引用的迭代器的类型是引用,可以是
const
,对于std::vector
,它可以与向量的项目类型完全不同.
The type of a a dereferenced iterator is a reference, it can be
const
, and for astd::vector
it can be very different from the vector's item type.
例如项目类型为bool
,您不想以bool
类型进行求和.
When the item type is e.g. bool
, you don't want to do the sum in bool
type.
以下代码是一种解决方案:
The following code is one solution:
#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
.
Note that you don't have to define your own sum
: there is std::accumulate
.
这篇关于C ++类型的解引用迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!