4

经过一番痛苦后,我设法将这个最小的 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

4

2 回答 2

8

文档中对此进行了解释:

当跳过元素时,过滤器适配器必须知道何时停止以避免超出基础范围的末尾。因此,过滤器迭代器由一对迭代器构成,指示要遍历的未过滤序列中的元素范围。

从下面的源代码中,您可以看到总是检查它们是否已到达末尾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()因此,您可以在构建结束迭代器时从代码中省略。

于 2013-03-20T20:43:08.400 回答
1

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

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

具体来说,您会看到最后一个参数是默认参数,它设置为Iterator()which 意味着它是默认构造的,对于某些类型的迭代器,它的行为类似于实际end()迭代器,它指向任何数组的末尾,即它指向垃圾。

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

于 2013-03-20T20:45:04.530 回答