boost::python and set::erase -> weird behaviour

╄→尐↘猪︶ㄣ 提交于 2019-12-05 07:47:39

I ran your example then added some assertions that I thought should hold in del():

assert(!(v_param < v_ptr));
assert(!(v_ptr < v_param));

One of them failed!

I dug into the implementation of operator< for boost::shared_ptr and found something strange: it compares the reference counts rather than the internal pointers! A little digging found a mailing list post about this issue with some helpful links to two C++ documents: N1590 which explains why people thought this was a good idea, and N2637 which explains why it wasn't.

It seems that the Boost people have not (yet?) adopted the N2637 recommendation, but C++11 has. So I built your test again using C++11 (g++ -std=c++0x), having removed using namespace boost; so as to use std::shared_ptr. This resulted in a horrible template-ridden error message which was solved by adding this at the top (easily derived from boost/smart_ptr/shared_ptr.hpp):

template<class T> inline T * get_pointer(std::shared_ptr<T> const & p)
{
    return p.get();
}

And it works!

If you can't use C++11, just implement your own custom comparator for your set which compares the pointers sanely:

template <typename T>
struct SmartComparator
{
    bool operator()(shared_ptr<T> const& lhs, shared_ptr<T> const& rhs) {
        return lhs.get() < rhs.get();
    }
};

Then this will work:

set< shared_ptr<Bar>, SmartComparator<Bar> > v_set;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!