1

我有一个 boost::ptr_vector 包含指向“可持有”类的指针。

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,但我显然在某个地方出错了,可能与“this”的使用有关。

在尝试编译时,我收到来自 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 的间接性感到困惑......提前感谢您的任何答案!

4

3 回答 3

2

我知道 std::find 需要第三个参数的值(不是指针),所以你传递了一个 ["begin", "end") 范围来寻找,以及你寻找的值

这是你的意思吗?

currentplanet->items.erase(std::find(currentplanet->items.begin(),
                                     currentplanet->items.end(),
                                     *this));

注意 *this

于 2012-11-11T07:37:37.943 回答
2

正如其他人所写 - 确实ptr_vector拥有您的对象的所有权,但如果您坚持能够自行删除对象ptr_vector- 使用 find_if,而不是 find:

Holdable* ptr = this;
currentplanet->items.erase(std::find_if(currentplanet->items.begin(),
                                        currentplanet->items.end(),
                                        [ptr](const Holdable& other) 
                                        {return ptr == &other;} ));

请注意,find使用 with*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)));
于 2012-11-11T10:39:37.667 回答
2

Alf 是正确的,但出于某种原因boost::ptr_vector(和其他相关boost::reversible_ptr_container容器)我认为应该被调用。通常,容器元素的迭代器将取消引用对容器的value_type.

boost:ptr_vector<T>::value_type是一个 typedef T*; 但是取消引用 aboost::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& 对象,而不是 T*。

取消引用 aboost::ptr_vector<T>::iterator结果为 a T&。这就是为什么您对 ptr_vector 的间接性感到困惑的原因,这就是为什么 to 的最后一个参数std::find()需要是一个holdable对象而不是一个holdable*.

最后,请注意 Xeo 关于ptr_vector获取指针所有权的评论应该被理解 - 在非常有限的情况下,对象想要删除自己可能是有意义的,但您应该充分理解,在该erase()调用之后,您可以不再对对象做任何事情。如果这不是您需要的行为,erase()那么您可能不想考虑使用release(),这将释放容器对指针的所有权并将其从容器中删除(因此对象不会被破坏)。

于 2012-11-11T09:46:10.400 回答