2016-09-22 99 views
2

我試圖寫在C + + 所以我有一個包含事件名稱的映射圖的一個觀察者模式中刪除項目 - 回調函數>矢量從STD的一個矢量::函數

回調函數存儲在矢量

std::function<void(void *)> 

所以地圖上看起來像

std::unordered_map<std::string, std::vector<std::function<void(void *)>>> 

我可以添加監聽器載體和接收和事件通知作出迴應。我的問題是執行分離。因此,std :: function無法進行比較,所以我們不需要擦除/刪除,所以我想搜索矢量並手動比較。

我發現this question使用std ::功能::目標與獲得訪問底層指針取得了成功,但由於我使用的std ::綁定初始化的回調,我不能用這個,:

std::function<void(void *)> fnCallback = std::bind(&wdog::onBark, this, std::placeholders::_1) 

我只想比較底層成員函數ptrs,甚至是與成員函數關聯的底層對象ptr進行比較。有什麼辦法嗎?

我想避免包裝在包含一個散列對象的成員函數PTR,雖然它看起來像我可能會走那條路......

+2

你能發表一個關於如何添加/刪除地圖項目的例子嗎? – Holt

+0

在我看來,你已經知道答案了...... :-) – skypjack

+1

如果沒有存儲指向有問題的對象的指針以用作關鍵字,則無法真正做到這一點。我的impl使用weak_ptr並在分派事件之前檢查集合以移除expired()。 Attach是(shared_from_this(),&class :: member),detach是(shared_from_this())。 – Robinson

回答

2

當我這樣做,我返回一個標記到聆聽代碼。

我通常的模式是在廣播公司有一個weak_ptr<function<sig>>,令牌是shared_ptr<void>(對於存儲的弱ptr)。

廣播時,我過濾出死目標,然後廣播。目標通過簡單地清除,銷燬或以其他方式丟棄他們的令牌來註銷。如果他們想永不註銷,那麼在他們的實例中的一個令牌向量是一種合理的方式。

如果你從未廣播過,可能會導致老舊的資源不必要地掛在身邊,所以在公共框架中,我可能想要一些有保證的東西。但它輕巧便捷,反之亦然。

+0

請問您可以發表一個什麼樣的代碼來說明上面的內容嗎? –

+0

@segme http://stackoverflow.com/a/34400239/1774667是SO上的前一個草圖。我不知道這是否是我公佈的最好的,但它應該給你的想法。 – Yakk