after some pain I managed to hack together this minimal example of boost filter_iterator
using namespace std;
std::function<bool(uint32_t)> stlfunc= [](uint32_t n){return n%3==0;};
int main()
{
vector<uint32_t> numbers{11,22,33,44,55,66,77,3,6,9};
auto start = boost::make_filter_iterator(stlfunc, numbers.begin(), numbers.end());
auto end = boost::make_filter_iterator(stlfunc, numbers.end() , numbers.end());
auto elem = std::max_element(start,end);
cout << *elem;
}
It works nice, but I wonder why the make_filter_iterator takes numbers.end()
?
I might be wrong to use it that way, I guestimated it from the C array example:
http://www.boost.org/doc/libs/1_53_0/libs/iterator/example/filter_iterator_example.cpp
That is explained in the docs:
When skipping over elements, it is necessary for the filter adaptor to know when to stop so as to avoid going past the end of the underlying range. A filter iterator is therefore constructed with pair of iterators indicating the range of elements in the unfiltered sequence to be traversed.
From the source below you can see the always check if they have reached the end in satisfy_predicate
:
void increment()
{
++(this->base_reference());
satisfy_predicate();
}
void satisfy_predicate()
{
while (this->base() != this->m_end && !this->m_predicate(*this->base()))
++(this->base_reference());
}
Also, as pointed out by Alex Chamberlain, the
constructors make it optional when passing the end iterator, for example: filter_iterator(Iterator x, Iterator end = Iterator());
(provided it is default constructible). So, you could omit numbers.end()
from your code when constructing the end iterator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With