D'une part, vous pouvez simplement définir l'opérateur == pour tout weak_ptr. Je suis sûr qu'il y a une raison pour laquelle cela n'est pas implémenté, ça peut probablement vous mordre plus tard.
template <typename T>
bool operator == (const std::tr1::weak_ptr<T>& a, const std::tr1::weak_ptr<T>& b)
{
return a.lock() == b.lock();
}
... et vous pourrez simplement appeler remove() comme d'habitude. C'est un peu extrême je suppose.
Si vous vous en tenez à l'approche remove_if(), vous pouvez vous débarrasser de la magie de liaison * en utilisant l'objet de fonction:
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();
}
};
puis l'utiliser comme ceci:
mylist.remove_if(EqPredicate(pItem));
Il ressemble à plus de code, mais vous pouvez compresser la classe EqPredicate, elle est principalement creuse. En outre, il pourrait être fait modèle pour l'utiliser avec des listes contenant des types autres que Item.
Oh, et vous passez weak_ptrs par référence partout y compris votre fonction de comparaison.
* bind n'est pas gratuit en termes de performances. Si vous attendez beaucoup d'appels Remove() et que vous vous souciez beaucoup des performances, il peut être utile de l'éviter.
Et que se passe-t-il si le pointeur faible ne peut pas être verrouillé parce que ce qu'il pointe vers est parti? – Omnifarious
En utilisant la réponse de sbk, p.lock() retournera un shared_ptr à p, qui ne correspondra pas à theItem.lock(), donc cela fonctionnera toujours. p.lock() ne lance jamais. –