如何从boost :: ptr_vector中删除“this”

时间:2012-11-11 03:24:07

标签: c++ boost ptr-vector

我有一个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的间接感到困惑......感谢您提前得到任何答案!

3 个答案:

答案 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_typeT*的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)));