【问题标题】:Sequence iterator? Isn't there one in boost?序列迭代器?没有一个在boost吗?
【发布时间】:2011-10-21 17:54:30
【问题描述】:

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

假设我们有一个将整数映射到类型 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* 不返回引用。

提前感谢您的帮助。

【问题讨论】:

  • CUDA Thrust 正是这样的东西,以避免不得不制作“微不足道的”显式序列。
  • 这让我想起了 Matthew Wilson 的 Fibonacci_sequence。它更像是您正在谈论的特定案例,但它至少可能会给您一些想法或灵感:-)
  • mrm:确切地说,我想要一个概括:)

标签: c++ boost iterator


【解决方案1】:

Boost.Utility 包含一个generator iterator adaptor。文档中的一个示例:

#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;
}

【讨论】:

    【解决方案2】:

    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);
    

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 不,很遗憾,transform_iterator 已经需要一个迭代器。
        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-11
          • 2017-06-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-22
          • 2018-07-14
          • 1970-01-01
          相关资源
          最近更新 更多