Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ boost::python和set::erase->;奇怪的行为_C++_Boost_C++11_Shared Ptr_Boost Python - Fatal编程技术网

C++ boost::python和set::erase->;奇怪的行为

C++ boost::python和set::erase->;奇怪的行为,c++,boost,c++11,shared-ptr,boost-python,C++,Boost,C++11,Shared Ptr,Boost Python,我正在尝试将对象存储在std::set中。这些对象是来自python环境的boost::shared_ptr。向集合中添加值不会引起任何问题。但是当我试图删除一个值时,即使我传递的是同一个引用,它也不会起作用。以下是一个例子: #include <set> #include <iostream> #include <boost/shared_ptr.hpp> #include <boost/python.hpp> using namespace

我正在尝试将对象存储在std::set中。这些对象是来自python环境的boost::shared_ptr。向集合中添加值不会引起任何问题。但是当我试图删除一个值时,即使我传递的是同一个引用,它也不会起作用。以下是一个例子:

#include <set>
#include <iostream>

#include <boost/shared_ptr.hpp>
#include <boost/python.hpp>

using namespace std;
using namespace boost;
using namespace boost::python;

struct Bar
{
    Bar() {}
};

struct Foo
{
    set< shared_ptr<Bar> > v_set;
    shared_ptr<Bar> v_ptr;

    Foo() {}

    void add( shared_ptr<Bar> v_param ) {
    cout << "storing " << v_param << "in v_set and v_ptr" << endl;
    v_set.insert(v_param);
    v_ptr = v_param;

    }

    void del( shared_ptr<Bar> v_param ) {
    cout << "deleting " << v_param << endl;
    if (v_param == v_ptr) {
        cout << "v_param == v_ptr" << endl;
    } else {
        cout << "v_param != v_ptr" << endl;
    }

    cout << "erasing from v_set using v_param" << endl;
    if (v_set.erase(v_param) == 0) {
        cout << "didn't erase anything" << endl;
    } else {
        cout << "erased !" << endl;
    }

    cout << "erasing from v_set using v_ptr" << endl;
    if (v_set.erase(v_ptr) == 0) {
        cout << "didn't erase anything" << endl;
    } else {
        cout << "erased !" << endl;
    }
    }
};

BOOST_PYTHON_MODULE (test)
{
    class_< Foo, shared_ptr<Foo> >("Foo")
        .def("add",&Foo::add)
        .def("remove",&Foo::del);

    class_< Bar, shared_ptr<Bar> >("Bar");    
}
现在是一个小python脚本:

from test import *

f = Foo()
b = Bar()

f.add(b)

f.remove(b)
结果如下:

storing 0x8c8bc58in v_set and v_ptr
deleting 0x8c8bc58
v_param == v_ptr
erasing from v_set using v_param
didn't erase anything
erasing from v_set using v_ptr
erased !
  • 我将0x8e89c58存储在集合内部和外部,以防万一
  • 我将相同的引用传递给两个调用(0x8e89c58)
  • 只是为了确保我检查v==val
  • 我试着用v来抹掉,它不起作用
  • 我试着用val擦除——它能用

我完全迷路了,看不出是什么原因造成的。任何输入?

我运行了您的示例,然后在
del()
中添加了一些我认为应该包含的断言:

而且它有效

如果您不能使用C++11,只需为您的集合实现您自己的自定义比较器,它可以对指针进行合理的比较:

template <typename T>
struct SmartComparator
{
    bool operator()(shared_ptr<T> const& lhs, shared_ptr<T> const& rhs) {
        return lhs.get() < rhs.get();
    }
};
模板
结构智能比较器
{
布尔运算符()(共享\u ptr const&lhs、共享\u ptr const&rhs){
返回lhs.get()
那么这就行了:

set< shared_ptr<Bar>, SmartComparator<Bar> > v_set;
setv\u set;

在同一个函数中使用“value”、“val”和“v”作为变量名,会使代码不必要地难以理解。对此,我深表歉意。我希望现在更清楚。哇。你回答的质量给我留下了深刻的印象。它确实解决了我的问题。非常感谢您抽出时间!
template<class T> inline T * get_pointer(std::shared_ptr<T> const & p)
{
    return p.get();
}
template <typename T>
struct SmartComparator
{
    bool operator()(shared_ptr<T> const& lhs, shared_ptr<T> const& rhs) {
        return lhs.get() < rhs.get();
    }
};
set< shared_ptr<Bar>, SmartComparator<Bar> > v_set;