[英]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.