问题描述
我想存储在一个std ::对象设置。这些对象的boost :: shared_ptr的<>,从Python环境的到来。添加值的集合不会造成任何麻烦。但是,当我试图抹掉一个值,即使我通过了非常相同的参考,它不会工作。下面是一个例子:
I'm trying to store objects in a std::set. Those objects are boost::shared_ptr<>, coming from the python environment. adding values to the set won't cause any troubles. But when I try to erase a value, even though I'm passing the very same reference, it won't work. Here is an example :
#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");
}
编译:
%> gcc -pthread -fno-strict-aliasing -march=i686 -mtune=generic -O2 -pipe -DNDEBUG -march=i686 -mtune=generic -O2 -pipe -fPIC -I/usr/include/python2.7 -c test.cpp -o test.o
%> g++ -pthread -shared -Wl,--hash-style=gnu -Wl,--as-needed build/temp.linux-i686-2.7/test.o -L/usr/lib -lboost_python -lpython2.7 -o test.so
现在,小python脚本:
and now, a small python script :
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擦除 - 它的工作原理
我完全失去了那里 - 看不出是什么原因造成这一点。任何输入?
I'm completely lost there - can't see what is causing this. Any input ?
推荐答案
我跑你的榜样,加入了一些说法,我认为应该在持有德尔()
:
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!
我挖成的实施运营商的LT;
为的boost :: shared_ptr的
并发现了一些奇怪的:它比较引用计数,而不是内部的指针!有一点点找到关于此问题的,提供一些有用的链接两个C ++文件:N1590这也解释了为什么人们认为这是一个好主意,N2637这就解释了为什么它不是
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.
看来,升压人没有(没有?)通过了N2637的建议,但C ++ 11。于是我重新建造你的测试使用C ++ 11( G ++ -std =的C ++ 0x
),在除去使用空间boost;
,以便使用的std :: shared_ptr的
。这导致其在顶部添加此解决一个可怕的模板缠身的错误信息(容易源自升压/ smart_ptr / shared_ptr.hpp
)
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();
}
和它的作品!
如果您不能使用C ++ 11,只需要实现自己的自定义比较你的一套指针三立比较:
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();
}
};
那么这将工作:
set< shared_ptr<Bar>, SmartComparator<Bar> > v_set;
这篇关于提高:: Python和设置::擦除 - &GT;怪异的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!