简体   繁体   English

boost :: filter_iterator也为end()调用谓词?

[英]boost::filter_iterator calls predicate also for end()?

I'm strugging with boost::filter_iterator. 我正在使用boost :: filter_iterator。 I use it to create a custom iterator skipping some elements. 我用它来创建一个跳过一些元素的自定义迭代器。 Those elements are contacts between some particles, and some contacts define their geometry (Contact::geom); 这些元素是某些粒子之间的接触,有些接触定义了它们的几何形状(Contact :: geom); I want to skip those, who don't define it (ie !Contact::geom). 我想跳过那些没有定义它的人(即!Contact :: geom)。 A shortened version looks like this (I probably couldn't make it shorter): 缩短版本看起来像这样(我可能无法缩短版本):

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 */
};

I keep getting this from the debugger: 我一直从调试器得到这个:

#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

If I am reading it right, the filter_iterator calls the predicate also on ContactContainer::end(), which is really ContactContainer::data.end(). 如果我正确读取它,filter_iterator也会在ContactContainer :: end()上调用谓词,它实际上是ContactContainer :: data.end()。 Is that the expected behavior? 这是预期的行为吗? Unfortunately the documentation shows only number filtering, and I am at loss as to how to proceed. 不幸的是,文档只显示了数字过滤,我不知道如何继续。

Could someone enlighten me? 有人可以开导我吗?

Cheers, 干杯,

Vaclav 瓦茨拉夫

The constructor for filter_iterator takes two iterators: begin and end, as in filter_iterator的构造函数有两个迭代器:begin和end,如

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

the following changes made your example execute for me: 以下更改使您的示例为我执行:

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

Test run: https://ideone.com/6qaeq 测试运行: https//ideone.com/6qaeq

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM