8

Is there any standard implementation (meaning stdlib or boost) of an iterator that wraps another iterator and gives only each nth element of it?

I first thought this would be possible with a fitting predicate and boost::filter_iterator, but the predicate gets only the value and not the base iterator, so it cannot tell the distance to the start.

Edit
To give some more information: The iterator should be compatible with functions like std::transform or std::copy. So it should be used like stdlib iterators.

Similar questions:
C++/STL: std::transform with given stride?
Non-unit iterator stride with non-random access iterators

Community
  • 1
  • 1
  • Can't you do e.g. `it += x` yourself? Or use [`std::advance`](http://en.cppreference.com/w/cpp/iterator/advance)? – Some programmer dude Oct 04 '12 at 11:44
  • No I cannot do this, as this is outside my reach. I want to pass the iterator to a function, that has an interface like `fn(beginIterator, endIterator)`. – Nobody moving away from SE Oct 04 '12 at 11:47
  • Do a search for e.g. [`c++ iterator adaptor`](https://www.google.se/search?q=c%2B%2B+iterator+adaptor&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a) – Some programmer dude Oct 04 '12 at 11:49
  • Well the question was about an existing one, so I could prevent doing it on my own. (I am afraid that there are some corner cases, where the implementation is not that trivial.) I already searched for some but I do not know the keywords to find exact problem I am facing. – Nobody moving away from SE Oct 04 '12 at 11:51

2 Answers2

9

Boost.Range provides a stride adaptor. Using boost::begin/boost::end would net you the associated iterators.

Luc Danton
  • 34,649
  • 6
  • 70
  • 114
  • I think that is what I am searching for. I can't believe I did not remember `stride` as the word I was looking for. – Nobody moving away from SE Oct 04 '12 at 11:52
  • I am afraid that this is not of use for me as I do not use Boost ranges. – Nobody moving away from SE Oct 04 '12 at 12:04
  • 1
    @Nobody You may want to amend your question then. – Luc Danton Oct 04 '12 at 12:23
  • 1
    It seems like one can rip out `strided_iterator`/`make_strided_iterator` from `boost::range_detail` but I assume that there is no guarantee that they will stay if they are in a detail namespace. – Nobody moving away from SE Oct 04 '12 at 12:43
  • @Nobody: What do you mean when you say that you do not use Boost ranges? "Boost range" is a concept that is modeled by many types, including standard containers (`std::list`, `std::vector`, etc.) and pair of iterators (`std::pair`). Thereby, I don't really see how you could not be using Boost ranges (if you have two iterators denoting a begin and an end, then you can make a Boost range out of it simply by putting them in a pair). – Luc Touraille Oct 04 '12 at 13:12
  • And like Luc said, if you want to work with a stride iterator rather than a stride range, you can always use `begin` and `end` to get the underlying iterators. – Luc Touraille Oct 04 '12 at 13:15
  • Note however that `strided` is a Single Pass Range, meaning that you wouldn't be able to use it with all algorithms. – Luc Touraille Oct 04 '12 at 13:19
  • @LucTouraille: That two Lucs are a bit confusing :) I did in fact not have a look at Boost.Range up to now. It looked to me like it was a type, that would not be compatible with stdlib iterator functions. – Nobody moving away from SE Oct 04 '12 at 13:27
  • @Nobody For future reference, the different libraries that make up the Boost collection of libraries are referred to with a dot: Boost.MPL, Boost.Iterators, Boost.Proto, Boost.Range etc. An entity in the `boost` namespace is qualified with help from the scope resolution operator: `boost::pair`, `boost::reference_wrapper` etc. – Luc Danton Oct 04 '12 at 15:53
5

You can use boost::filter_iterator with predicate like:

 template< typename T, int N >
 struct EveryNth {
    bool operator()(const T&) { return m_count++ % N == 0; }
    EveryNth() : m_count(0) {}
    private:
      int m_count;
 };
Zdeslav Vojkovic
  • 14,391
  • 32
  • 45