在地图中存储 boost::signals2 信号?

Posted

技术标签:

【中文标题】在地图中存储 boost::signals2 信号?【英文标题】:Storing a boost::signals2 signal in a map? 【发布时间】:2012-06-04 15:15:47 【问题描述】:

我面临以下问题:我想在地图中存储多个boost::signals2 信号变量。由于这些信号是不可复制的,这显然是行不通的。我该如何解决这个问题?我已经找到this older question。在其中,一张海报建议将信号存储为shared_ptr。这是唯一的方法吗?它有什么缺点,或者更重要的是,它是否安全

【问题讨论】:

您也可以存储boost::signals2::signal *,但shared_ptr 只是一种方便的方式,无需担心删除对象。 安全是什么意思? @wroniasty 我只是想知道 boost::signals2 是否打算以这种方式使用。我不想介绍依赖于无证行为的代码。 好吧,一个不能安全存储在shared_ptr中的类坏了。 【参考方案1】:

正如一些评论员所指出的:将shared_ptrs 用于信号是非常安全的。我的实现工作正常并且在此期间已经过彻底测试,我很高兴地报告确实没有问题:)

【讨论】:

【参考方案2】:

如果不打算共享信号,您可以将分配在堆上的 boost::signal 对象存储在 Boost Pointer Container 内:

Boost.Pointer Container 提供了用于存放堆分配的容器 以异常安全的方式和最小开销的对象。

boost 指针容器存储指向其元素的指针,并在必要时自动删除这些堆对象。 API 试图隐藏元素由指针存储的事实,并尽可能返回元素引用。

例子:

#include <iostream>
#include <map>
#include <string>
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/signals.hpp>

void foo() std::cout << "foo\n";

void bar() std::cout << "bar\n";

int main()

    typedef boost::signal<void ()> Signal;
    boost::ptr_map< std::string, Signal> sigmap;
    sigmap["foo"].connect(&foo);
    sigmap["bar"].connect(&bar);
    sigmap["foo"](); // emit signal associated with "foo"
    sigmap["bar"](); // emit signal associated with "bar"

【讨论】:

【参考方案3】:

由于它不可复制且不可移动(可能在最新版本中已更改)。对于 std::map 如果您不想使用 shared_ptr ,则可以使用 operator[] 而不是 insert 或 emplace 方法,因为 operator[] 如果 key_value 不存在则构造 mapped_type 。显然,当您要使用先前分配的插槽添加信号时,它不能解决问题。

typedef boost::signal2... Signal;
std::map<int, Signal> sigmap;
sigmap[1]; // constructs signal using default constructor
sigmap[2].connect(slot); // constructs signal and connects slot

【讨论】:

以上是关于在地图中存储 boost::signals2 信号?的主要内容,如果未能解决你的问题,请参考以下文章

boost--signal

从 boost::signals2 安全断开

boost::signals2::signal 输出错误?

如何比较 boost::signals2 中的插槽类型

使用 boost::signals2 和卸载 DLL 时访问冲突

使用 boost::signals2 的编译时间非常慢