【问题标题】:remove an item from a vector of std::function从 std::function 的向量中删除一个项目
【发布时间】:2016-09-22 08:09:29
【问题描述】:

我正在尝试用 C++ 编写一个观察者模式 所以我有一个包含 eventname -> 回调函数向量的地图

回调函数存储在一个向量中

std::function<void(void *)>

所以地图看起来像

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

我可以将侦听器添加到向量并接收和响应事件通知。我的问题是实现分离。

所以std::function不能比较,所以erase/remove就出来了,所以我想搜索vector并手动比较。

我发现 this question 成功使用 std::function::target 访问底层指针,但我不能使用它,因为我正在使用 std::bind 来初始化回调:

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

我只想比较底层的成员函数ptr,甚至是和该成员函数关联的底层对象ptr比较。有什么办法吗?

我想避免将成员 fn ptr 包装在包含哈希的对象中,尽管看起来我可能不得不这样做......

【问题讨论】:

  • 您能否发布一个有关如何从地图中添加/删除项目的示例?
  • 在我看来你已经知道答案了... :-)
  • 如果不存储指向相关对象的指针以用作键,您就无法真正做到这一点。我的 impl 使用weak_ptr 并在发送事件之前检查集合以删除 expired() 。附加是 (shared_from_this(), &class::member),分离是 (shared_from_this())。
  • 示例太长(模板和多个文件),对不起 Holt。

标签: c++ c++11 vector std-function


【解决方案1】:

当我这样做时,我将一个令牌返回给监听代码。

我通常的模式是在广播器中有一个weak_ptr&lt;function&lt;sig&gt;&gt;,令牌是一个shared_ptr&lt;void&gt;(到存储的弱指针)。

广播时,我过滤掉死目标,然后广播。目标只需清除、销毁或以其他方式丢弃其令牌即可取消注册。如果他们不想注销,那么在他们的实例中使用令牌向量是一种合理的方式。

如果你从不广播这可能会导致旧的死资源不必要地闲置,所以在公共框架中,我可能想要一些有更好保证的东西。但它是轻量级的,简单快捷。

【讨论】:

  • 能否请您发布上面说明的示例代码?
  • @segme stackoverflow.com/a/34400239/1774667 是之前关于 SO 的草图。我不知道这是否是我公开发布的最好的,但它应该给你一个想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 2012-11-01
  • 2011-06-02
相关资源
最近更新 更多