我有一个boost :: ptr_vector,其中包含指向“holdable”类的指针。
boost::ptr_vector<holdable> items;
我从可保持类中向此向量添加新项目,如下所示:
currentplanet->items.push_back(this);
其中currentplanet是指向包含ptr_vector的类的对象的指针。这一切都很好。
我感到困惑的是如何从ptr_vector中的一个函数中删除一个条目。我在尝试:
currentplanet->items.erase(std::find(currentplanet->items.begin(),
currentplanet->items.end(),
this));
按照这里类似问题的答案:How to erase elements from boost::ptr_vector,但我显然在某处出错了,可能是关于“这个”的使用。
在尝试编译时,我收到来自stl_algo.h的错误
stl_algo.h|174|error: no match for 'operator==' in '__first.boost::void_ptr_iterator<VoidIter, T>::operator*
[with VoidIter = __gnu_cxx::__normal_iterator<void**, std::vector<void*, std::allocator<void*> > >,
T = holdable]() == __val'|
我确定这是显而易见的事情,但我可能会对ptr_vector的间接感到困惑......感谢您提前得到任何答案!
答案 0 :(得分:2)
我理解std :: find需要第三个参数的值(不是指针),所以你传递一个[“begin”,“end”)范围来搜索,你找到的值
这是你的意思吗?
currentplanet->items.erase(std::find(currentplanet->items.begin(),
currentplanet->items.end(),
*this));
注意* this
答案 1 :(得分:2)
Alf is correct,但出于某种原因,我认为boost::ptr_vector
(以及其他相关的boost::reversible_ptr_container
容器)有点特殊。通常,容器元素的迭代器将取消引用容器的value_type
。
boost:ptr_vector<T>::value_type
是T*
的typedef;但取消引用boost::ptr_vector<T>::iterator
不会导致T*
引用。
来自Boost文档(http://www.boost.org/doc/libs/1_52_0/libs/ptr_container/doc/reversible_ptr_container.html):
另请注意
typedef ... iterator
允许人们迭代T&amp;对象,而不是T *。
取消引用boost::ptr_vector<T>::iterator
会产生T&
。这就是为什么你被ptr_vector的间接混淆了,这就是为什么std::find()
的最后一个参数必须是holdable
对象而不是holdable*
。
最后,请注意Xeo关于ptr_vector
获取指针所有权的评论应该被理解 - 在非常有限的情况下,对象想要删除它本身可能是有意义的,但你应该完全这样做了解在erase()
调用之后,您无法对该对象执行任何其他操作。如果这不是您需要的行为,而不是erase()
,您可能需要考虑使用release()
,这将释放容器对指针的所有权以及从容器中删除它(因此对象不会是破坏)。
答案 2 :(得分:2)
正如其他人写的那样 - ptr_vector
确实取得对象的所有权,但如果你坚持能够将对象从ptr_vector
中删除 - 请使用find_if,而不是找到:< / p>
Holdable* ptr = this;
currentplanet->items.erase(std::find_if(currentplanet->items.begin(),
currentplanet->items.end(),
[ptr](const Holdable& other)
{return ptr == &other;} ));
请注意,与find
一起使用的*this
可能会找到等于*this
的其他对象......
对于仍然不支持lambda表达式的编译器(这个从[ptr]
开始),使用你自己的谓词:
struct CompareToPtr {
CompareToPtr(Holdable* ptr) : ptr(ptr) {}
bool operator () (const Holdable& other) const { return &other == ptr; }
Holdable* ptr;
};
currentplanet->items.erase(std::find_if(currentplanet->items.begin(),
currentplanet->items.end(),
CompareToPtr(this)));