How can I use std :: remove in a container with std :: tr1 :: weak_ptr?

If I had an STL container, tell me a list of pointers, I could delete them, as in the example below. This does not work with the weak_ptrs container because they cannot be compared since they must first be blocked. What can I do?

void MyClass::RemoveItem(std::tr1::weak_ptr<Item> const & pItem)
{
    mylist.remove(pItem);
}
+3
source share
3 answers

For one thing, you can simply define operator == for any weak_ptr. I am sure that the reason is that this is not implemented, perhaps it will bite you at a later moment.

template <typename T>
bool operator == (const std::tr1::weak_ptr<T>& a, const std::tr1::weak_ptr<T>& b)
{
    return a.lock() == b.lock();
}

... and you can just call remove () as usual. I think this is a little extreme.

remove_if(), *, :

struct EqPredicate
{
    const boost::weak_ptr<Item>& theItem;

    EqPredicate(const boost::weak_ptr<Item>& item) : theItem(item) 
    {
    }

    bool operator () (const boost::weak_ptr<Item>& p) const 
    { 
        return p.lock() == theItem.lock(); 
    }
};

:

mylist.remove_if(EqPredicate(pItem));

, EqPredicate, . , , , , Item.

, weak_ptrs , .

* bind . Remove() , , .

+5

, , .

weak_ptrs .

    bool weak_ptr_comparsion(Item::wPtr  a, Item::wPtr  b)
    {
        return a.lock() == b.lock();
    }

    void MyClass::RemoveItem(Item::wPtr const & pItem)
    {
        mylist.remove_if(std::tr1::bind(weak_ptr_comparsion, pItem, 
                         std::tr1::placeholders::_1));
    }

<tr1/functional>

0

I think the problem with the sbk approach is that the weak_ptr == operator has potential for race. There is no guarantee that shared_ptr for a or b exists even when returning from the == operator, which simplifies the misinterpretation of the resulting code.

With it, it seems you can best of all:

if(a == b) {
  boost::shared_ptr<Item> a_locked(a.lock());
  boost::shared_ptr<Item> b_locked(b.lock());
  // It is an error to assume a_locked == b_locked here
  // It is an error to assume a.lock() == b.lock() here
  // It is an error to assume a.get() or b.get() here
}

which is not so useful. Now, if you repeated the container, you can still remove the iterators at this point, but there are many more cases where you would end up with a slightly incorrect comparison.

0
source

Source: https://habr.com/ru/post/1717080/


All Articles