问题 跳过迭代器


我有一系列值,我想传递给一个需要的函数 (iterator begin, iterator end) 对。但是,我只希望处理原始序列中的每个第二个元素。

有没有一种很好的方法使用Standard-Lib / Boost创建一个迭代器外观,允许我传入原始序列?我认为这样的简单事情已经在boost迭代器或范围库中,但我没有找到任何东西。

或者我错过了另一个完全明显的方法来做到这一点?当然,我知道我总是可以选择将值复制到另一个序列,但这不是我想要做的。

编辑: 我知道 filter_iterator,但过滤值 - 它不会改变迭代的进展方式。


11500
2018-04-16 10:48


起源

我问了一个关于同一主题的略有不同的问题: stackoverflow.com/questions/3046747/c-stl-selective-iterator,bt我特意请求没有Boost,然后不是很有帮助:( - rubenvb


答案:


我想你想要的 提高::适配器::跨进


6
2017-09-23 22:03





struct TrueOnEven {
 template< typename T >
 bool operator()(const T&) { return mCount++ % 2 == 0; }
 TrueOnEven() : mCount(0) {}
 private:
  int mCount;
};

int main() {
 std::vector< int > tVec, tOtherVec;
 ...
 typedef boost::filter_iterator< TrueOnEven, int > TakeEvenFilterType;

 std::copy( 
  TakeEvenFilterType(tVec.begin(), tVec.end()),
  TakeEvenFilterType(tVec.end(), tVec.end()),
  std::back_inserter(tOtherVec));
}

说实话,这不仅仅是美观和直观。我写了一个简单的“枚举器”库,包括懒惰的集成查询,以避免像上面那样的hotchpotch ..它允许你写:

Query::From(tVec.begin(), tVec.end())
.Skip<2>()
.ToStlSequence(std::back_inserter(tOtherVec));

哪里 Skip<2> 基本上实例化一个通用的“过滤器”,它跳过每第N个(在这种情况下每秒)元素......

干杯,

保罗


3
2018-04-16 11:19



+1用于识别这只是一个愚蠢的黑客。它还对内部算法如何使用迭代器以及如何使用它做了很多假设 filter_iterator 使用谓词。例如,如果 operator() 对于给定的迭代器,它被评估两次,一切都不同步。 - ltjax
嗯,严格来说,如果filter_iterator归类为除以外的任何内容 std::input_iterator 要么 boost::SinglePass。你应该写一个完整的 skipping_iterator 这看起来更难...... - Paul Michalik


这是Boost的 过滤迭代器。这正是你想要的。

更新: 对不起,读错了。这是Boost中所有迭代器funkiness的列表:

http://www.boost.org/doc/libs/1_46_1/libs/iterator/doc/#specialized-adaptors

我认为一个带有重载的普通iterator_adaptor operator++ 只需增加底层迭代器值两次即可。


2
2018-04-16 11:01



不它不是。过滤器迭代器使用值的谓词过滤序列 - 但我想在迭代器上有一个谓词(如果你想把它想象为过滤)。基本上,我只是想呈现 +=2 如 ++ 到我的内部运营商 - ltjax
问题是应用(在实现中)operator ++两次可以结束容器,而不检查跳过元素是否已经是end()迭代器。 Althogh我正在考虑for循环(skip_iterator it = v.begin(); it!= v.end(); ++ it){} - alfC
alfC:你需要检查一下 it != end 在 - 的里面 operator++,在第二次调用unlying iterator之前 operator++。 - rubenvb
@rubenvb,但对于这种情况,迭代器必须知道 end内部。你是否可以作为迭代器的一部分结束,或者你将它传递给它 next (++)功能?在任何情况下,这在迭代器的上下文中都没有任何意义。 - alfC