序列迭代器?不是有助推器吗?

Sequence iterator? Isn't there one in boost?

本文关键字:助推器 迭代器      更新时间:2023-10-16

有时我觉得需要某种迭代器(除了这个问题标题的前缀之外,我不能为它起一个好名字)。

假设我们有一个函数(或函数对象),它将一个整数映射为类型t。也就是说,我们有一个数学序列的定义,但实际上并没有将它存储在内存中。我想用它做一个迭代器。迭代器类看起来像这样:

template <class F, class T>
class sequence_iterator : public std::iterator<...>
{
    int i;
    F f;
    public:
    sequence_iterator (F f, int i = 0):f(f), i(i){}
    //operators ==, ++, +, -, etc. will compare, increment, etc. the value of i.
    T operator*() const
    {
        return f(i);
    }    
};
template <class T, class F>
sequence_iterator<F, T> make_sequence_iterator(F f, int i)
{
    return sequence_iterator<F, T>(f, i);
}

也许我太天真了,但是我个人觉得这个迭代器非常有用。例如,假设我有一个函数来检查一个数字是否是素数。我要计算区间[a,b]内质数的个数。我会这样做的;

int identity(int i)
{
   return i;
}
count_if(make_sequence_iterator<int>(identity, a), make_sequence_iterator<int>(identity, b), isPrime);

因为我发现了一些有用的东西(至少在我看来),我绝对肯定它存在于boost或标准库中。我就是找不到。那么,在boost中有类似的东西吗?。在非常不可能的情况下,实际上没有,然后我要写一个,在这种情况下,我想知道你的意见,我是否应该做iterator_category random_access_iterator_tag。我担心的是,这不是一个真正的RAI,因为operator*不返回引用。

提前感谢您的帮助。

boost::counting_iteratorboost::transform_iterator应该可以做到这一点:

template <typename I, typename F>
boost::transform_iterator<
    F,
    boost::counting_iterator<I>>
make_sequence_iterator(I i, F f)
{
    return boost::make_transform_iterator(
        boost::counting_iterator<I>(i), f);
}

用法:

std::copy(make_sequence_iterator(0, f), make_sequence_iterator(n, f), out);

我将其称为整数映射迭代器,因为它将函数映射到整数的子序列上。不,我从未在Boost或STL中遇到过这种情况。我不确定为什么会这样,因为你的想法与流迭代器的概念非常相似,流迭代器也通过调用函数来生成元素。

是否需要随机访问迭代取决于您。我首先会尝试构建一个正向或双向迭代器,因为(例如)如果一次性生成和存储整数序列,那么对整数序列的重复二进制搜索可能会更快。

boost::transform_iterator是否满足您的需求?boost中有几个有用的迭代器适配器,文档在这里。

我认为boost::counting_iterator是您正在寻找的,或者至少是最接近的。是否有你想要的东西它没有提供?可以这样做,例如:

std::count_if(boost::counting_iterator<int>(0),
      boost::counting_iterator<int>(10),
      is_prime); // or whatever ...

简而言之,它是对连续值的惰性序列的迭代器。

实用程序包含一个生成器迭代器适配器。文档中的一个示例:

#include <iostream>
#include <boost/generator_iterator.hpp>
class my_generator
{
public:
    typedef int result_type;
    my_generator() : state(0) { }
    int operator()() { return ++state; }
private:
    int state;
};
int main()
{
    my_generator gen;
    boost::generator_iterator_generator<my_generator>::type it =
      boost::make_generator_iterator(gen);
    for (int i = 0; i < 10; ++i, ++it)
        std::cout << *it << std::endl;
}