C ++类型的解引用迭代器

时间:2016-07-21 21:12:54

标签: c++ iterator

我尝试创建一个对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&amp;'

经过一些研究后我发现了这个: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功能在我删除后无法正常工作

4 个答案:

答案 0 :(得分:0)

decltype(*first)返回引用,否则我们将无法编写

之类的内容
*first = 7;

关于difference_type,我们不清楚你要做什么。单词typename是必需的,以告诉编译器所谓的依赖类型(通常情况是::之后的任何类型)是模板而不是值。

答案 1 :(得分:0)

试试这个:

#include <type_traits>

template <
    typename Iter,
    typename Ret = typename std::decay<decltype(*std::declval<Iter>())>::type>
Ret f(Iter first, Iter last)
{
    Ret sum {};
    for (; first != last; ++first) { sum += *first; }
    return sum;
}

答案 2 :(得分:0)

有两个主要问题:

  • aa dereferenced iterator的类型是引用,它可以是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;
}

请注意,您无需定义自己的sumstd::accumulate

答案 3 :(得分:-1)

你随机做了一件事,它是随机的。 distance_type与您的问题无关,它是一种表示测量两个迭代器之间距离的结果的类型。由于它通常是整数类型,因此您最终能够在算术中使用它。

最初的问题是由于解除引用迭代器会返回一个指向底层对象的(const)指针这一事实 - 这是需要的,所以像

这样的代码
*it = 10;

会做你想做的事情(或者无法为const迭代器编译)。

typename关键字是必需的,但此处已typename使用此处有足够的重复项。