2013-03-20 12 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

相關問題