C ++类型的解引用迭代器 [英] C++ type of dereferenced iterator

查看:225
本文介绍了C ++类型的解引用迭代器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图制作一个对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 a std::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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆