2013-03-20 13 views
4

经过一番痛苦我设法破解一起提升filter_iterator为什么boost filter_iterator有怪异的make_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()的这个小例子? 我可能是错用这种方式,我guestimated它从C数组例如:
http://www.boost.org/doc/libs/1_53_0/libs/iterator/example/filter_iterator_example.cpp

回答

7

即在解释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()

+0

它也解释说,它是可选的,如果基础迭代器是默认构造的(并且代表你想要的范围的末尾) – 2013-03-20 20:44:15

+0

即时混淆...正常迭代器不知道何时停止,那为什么要filter_iterator呢?我的意思是你不做(auto it = v.begin; it!= std :: vector :: iterator(); ++ it) – NoSenseEtAl 2013-03-20 20:47:58

+0

@NoSenseEtAl是不是UB增加一个'end'迭代器? – 2013-03-20 20:48:47

1

如果你看看你make_filter_iterator模板的声明,你看到它看起来像这样:

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

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

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

+1

'std :: vector :: const_iterator()!= std :: vector :: cend()' – 2013-03-20 20:46:12

+0

我不相信有任何保证标准库容器迭代器默认构造等于结束迭代器。 – 2013-03-20 20:49:33

+0

@DaveS看来你是对的,我已经适当地修改了我的答案。 – 2013-03-20 20:51:02

相关问题