[英]How can I use std::remove on a container with std::tr1::weak_ptr?
如果我有一个STL容器,说一个指针列表,我可以删除它们,如下面的例子。 使用weak_ptrs容器时,这不起作用,因为它们无法进行比较,因为它们需要先锁定。 我能做什么?
void MyClass::RemoveItem(std::tr1::weak_ptr<Item> const & pItem)
{
mylist.remove(pItem);
}
首先,您可以为任何weak_ptr定义operator ==。 我确定这是没有实施的原因,它可能会在以后咬你。
template <typename T>
bool operator == (const std::tr1::weak_ptr<T>& a, const std::tr1::weak_ptr<T>& b)
{
return a.lock() == b.lock();
}
...你可以像往常一样调用remove()。 我猜这有点极端。
如果你坚持使用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()调用并且非常关注性能,那么避免它可能会很好。
我认为sbk方法的问题是weak_ptr运算符==具有竞争的潜力。 即使从operator ==返回,也不能保证a或b存在shared_ptr,这使得很容易误解结果代码。
有了它,你可以做的最好的事情是:
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
}
哪个没用。 现在,如果你在一个容器上进行迭代,你仍然可以在这一点上删除迭代器,但是还有更多的情况你最终只会稍微做出错误的比较。
只因为我一直在寻找答案。
创建一个函数来比较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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.