如果我有一個STL容器,說一個指針列表,我可以像下面的例子那樣去除它們。對於weak_ptrs容器,這不起作用,因爲它們無法進行比較,因爲它們需要先被鎖定。我能做什麼?如何在std :: tr1 :: weak_ptr的容器上使用std :: remove?
void MyClass::RemoveItem(std::tr1::weak_ptr<Item> const & pItem)
{
mylist.remove(pItem);
}
如果我有一個STL容器,說一個指針列表,我可以像下面的例子那樣去除它們。對於weak_ptrs容器,這不起作用,因爲它們無法進行比較,因爲它們需要先被鎖定。我能做什麼?如何在std :: tr1 :: weak_ptr的容器上使用std :: remove?
void MyClass::RemoveItem(std::tr1::weak_ptr<Item> const & pItem)
{
mylist.remove(pItem);
}
一件事,你可以只定義的==操作符的任何weak_ptr的。我相信這是沒有實現的原因,它可能會在稍後的時候咬你。
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。
*綁定不是免費的性能。如果您希望進行大量的Remove()調用並關心性能,則可能需要避免它。
只因爲我搜索像永遠找到答案。
創建一個函數來比較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>
好像你應該使用一個函數對象,並通過引用來獲取參數。 – rlbond 2009-09-07 18:43:23
我認爲sbk的方法存在的問題是weak_ptr運算符==有可能進行比賽。即使你從operator ==返回,也不能保證shared_ptr對a或b存在,這很容易誤解結果代碼。
有了它,似乎你能做的最好的是:
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
}
這是不是有用。現在,如果你迭代了一個容器,你仍然可以在這個時候刪除迭代器,但是還有很多情況下你最終只會做出錯誤的比較。
如果弱指針不能被鎖定,會發生什麼,因爲它指向的內容已經消失了? – Omnifarious 2009-09-07 20:28:54
使用sbk的答案,p.lock()會返回一個shared_ptr給p,它不會匹配Item.lock(),所以它仍然可以工作。 p.lock()永遠不會拋出。 – 2010-05-21 14:02:13