为什么boost filter_iterator具有奇怪的make_filter_iterator函数?

时间:2013-03-20 20:36:35

标签: c++ boost boost-iterators

在经历了一些痛苦之后,我设法将这个最小的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;
}

它很好用,但我想知道为什么make_filter_iterator需要numbers.end()? 我可能错误地使用它,我从C数组示例中猜测它:
http://www.boost.org/doc/libs/1_53_0/libs/iterator/example/filter_iterator_example.cpp

2 个答案:

答案 0 :(得分:8)

docs

中对此进行了解释
  

跳过元素时,过滤器适配器必须使用   知道何时停止,以避免超过底层的结束   范围。因此,过滤器迭代器由一对构造   迭代器,指示未过滤序列中元素的范围   被遍历。

从下面的来源,您可以看到始终检查它们是否已在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());
}

另外,正如Alex Chamberlain指出的那样  构造函数在传递结束迭代器时使其成为可选项,例如:filter_iterator(Iterator x, Iterator end = Iterator());(前提是它是默认的可构造的)。因此,在构造结束迭代器时,可以省略代码中的numbers.end()

答案 1 :(得分:1)

如果您查看make_filter_iterator模板的声明,就会看到如下所示:

template <class Predicate, class Iterator>
filter_iterator<Predicate,Iterator>
make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());

具体来说,你看到最后一个参数是一个默认参数,它被设置为Iterator(),这意味着它是默认构造的,对于某些类型的迭代器,它的行为就像实际的{{1迭代器,它指向一个超过任何数组末尾的一个,即它指向垃圾。

大多数容器类型都需要传递实际的end()迭代器。