2011-05-19 64 views
0

我在與boost :: filter_iterator結緣。我用它來創建一個跳過一些元素的自定義迭代器。這些元素是一些粒子之間的接觸,一些接觸定義了它們的幾何形狀(Contact :: geom);我想跳過那些沒有定義它的人(即!Contact :: geom)。縮短的版本是這樣的(我可能不會把它縮短了):boost :: filter_iterator也爲end()調用謂詞?

struct Contact{ 
    shared_ptr<CGeom> geom; 
    bool isReal(){ return (bool)geom; } 
    /* some other data... */ 
}; 

struct ContactContainer{ 

    // this is the underlying container 
    typedef vector<shared_ptr<Contact> > ContainerT; 
    ContainerT data;         

    // predicate defining whether we skip this contact or not 
    struct IsReal{ 
     bool operator()(shared_ptr<Contact>& c){ return c && c->isReal(); } 
     bool operator()(const shared_ptr<Contact>& c){ return c && c->isReal(); } 
    }; 

    typedef boost::filter_iterator<IsReal,ContainerT::iterator> iterator; 
    typedef boost::filter_iterator<IsReal,ContainerT::const_iterator> const_iterator; 

    // return proxy iterator 
    iterator begin(){ return data.begin(); } 
    iterator end(){ return data.end(); } 
    const_iterator begin() const { return const_iterator(data.begin()); } 
    const_iterator end() const { return const_iterator(data.end()); } 
    size_t size() const { return data.size(); } 
}; 

Now at one place of the code, I iterate over the ContactContainer using BOOST_FOREACH, which should filter out contacts where !c->isReal() automatically: 

BOOST_FOREACH(const shared_ptr<Contact>& c, contacts){ 
    /* do something here */ 
}; 

我一直在調試器得到這個:

#4 <signal handler called> 
#5 0x00007fc94cdc4ad4 in boost::shared_ptr<CGeom>::operator CGeom* boost::shared_ptr<CGeom>::* (this=0x2dee04a518aa88) at /usr/include/boost/smart_ptr/detail/operator_bool.hpp:47 
#6 0x00007fc94cdbefe4 in Contact::isReal (this=0x2dee04a518aa80) at /home/eudoxos/yade/build-tr2/dbg/include/yade/pkg/dem/Particle.hpp:101 
#7 0x00007fc94ce2a2da in ContactContainer::IsReal::operator() (this=0x7fff1ebe1038, c=...) at pkg/dem/ContactContainer.cpp:8 
#8 0x00007fc94d0a9e05 in boost::filter_iterator<ContactContainer::IsReal, __gnu_cxx::__normal_iterator<boost::shared_ptr<Contact>*, std::vector<boost::shared_ptr<Contact>, std::allocator<boost::shared_ptr<Contact> > > > >::satisfy_predicate (this=0x7fff1ebe1030) at /usr/include/boost/iterator/filter_iterator.hpp:100 
#9 0x00007fc94d0a5ae7 in boost::filter_iterator<ContactContainer::IsReal, __gnu_cxx::__normal_iterator<boost::shared_ptr<Contact>*, std::vector<boost::shared_ptr<Contact>, std::allocator<boost::shared_ptr<Contact> > > > >::filter_iterator (this=0x7fff1ebe1030, x=..., end_=...) at /usr/include/boost/iterator/filter_iterator.hpp:72 
#10 0x00007fc94d09b311 in ContactContainer::end (this=0x3df5b40) at /home/eudoxos/yade/build-tr2/dbg/include/yade/pkg/dem/ContactContainer.hpp:46 
#11 0x00007fc94d0b098b in boost::range_detail::range_end<ContactContainer> (c=...) at /usr/include/boost/range/end.hpp:50 
#12 0x00007fc94d0ace87 in boost::end<ContactContainer> (r=...) at /usr/include/boost/range/end.hpp:99 
#13 0x00007fc94d0a95c1 in boost::foreach_detail_::end<ContactContainer, mpl_::bool_<false> > (col=...) at /usr/include/boost/foreach.hpp:693 

如果我讀它的權利,在filter_iterator調用謂詞也在ContactContainer :: end()上,它實際上是ContactContainer :: data.end()。這是預期的行爲?不幸的是,文檔只顯示數字過濾,並且我不知道如何繼續。

有人能教導我嗎?

乾杯,

瓦茨拉夫

+1

跳過如何完成?是否存在* you *跳過end()或end()之前的值的風險? – 2011-05-19 13:44:03

回答

2

filter_iterator的構造函數兩個迭代器:開始和結束,在

filter_iterator(Iterator x, Iterator end = Iterator()); 

以下更改做你的榜樣執行對我來說:

iterator begin(){ return iterator(data.begin(), data.end()); } 
iterator end(){ return iterator(data.end(), data.end());} 

試運行:https://ideone.com/6qaeq

+1

謝謝,它的工作原理! (不要指責提升,但我想知道爲什麼它的文檔有時是不可讀的) – eudoxos 2011-05-20 09:46:52