Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ boost::signals2的包装器,具有通用插槽的生存期管理_C++_Templates_Signals_Boost Signals2 - Fatal编程技术网

C++ boost::signals2的包装器,具有通用插槽的生存期管理

C++ boost::signals2的包装器,具有通用插槽的生存期管理,c++,templates,signals,boost-signals2,C++,Templates,Signals,Boost Signals2,我想为向插槽发送信号的模块(线程)创建一个boost::signals2包装类。也就是说,模块应该通过从我的信号类继承来获得典型的简单信号功能(例如,公共连接(…)方法)。我还想隐藏实际使用的信号插槽实现 具体插槽继承自通用插槽基类,该基类具有定义其签名的模板参数。插槽只是具有适当签名的函子 这个问题与这个问题有些关联。插槽存储为共享_ptr,需要进行寿命管理。也就是说,信号类应该持有对插槽的引用,以便在信号本身退出时保持其活动。因此,我无法连接std::函数或类似函数。我必须连接插槽基类的共享

我想为向插槽发送信号的模块(线程)创建一个boost::signals2包装类。也就是说,模块应该通过从我的信号类继承来获得典型的简单信号功能(例如,公共连接(…)方法)。我还想隐藏实际使用的信号插槽实现

具体插槽继承自通用插槽基类,该基类具有定义其签名的模板参数。插槽只是具有适当签名的函子

这个问题与这个问题有些关联。插槽存储为共享_ptr,需要进行寿命管理。也就是说,信号类应该持有对插槽的引用,以便在信号本身退出时保持其活动。因此,我无法连接std::函数或类似函数。我必须连接插槽基类的共享\u ptr

我目前的方法,到目前为止没有线程安全(MSVC 2010):

模板
类槽;
模板
班槽
{
公众:
类型def R Ret_类型;
公众:
虚拟~Slot(){}
虚拟Ret_类型运算符()()=0;
};
模板
班槽
{
公众:
类型def R Ret_类型;
类型定义A1 Arg1_类型;
公众:
虚拟~Slot(){}
虚拟Ret_类型运算符()(Arg1_类型)=0;
};
//以此类推,以获得更多的论据
/*
信号类。
该类基本上是boost::signals2类的包装器,具有
插槽的生存期管理。
插槽通过存储的共享ptr连接
在std::vector中,确保插槽至少与信号一样长。
*/
模板
类信号
{
公众:
类型DEF插槽\U类型;
typedef boost::signals2::signal BoostSignal;
typedef typename BoostSignal::插槽\ U型BoostSlot;
公众:
虚拟~Signal(){}
无效连接槽(标准::共享槽);
受保护的:
//空洞发射信号(…);
//void disconnectAllSlots();
私人:
增强信号信号;
///用于生命周期管理的插槽共享ptr向量
std::向量slotsVec;
};
模板
无效信号::连接插槽(标准::共享插槽)
{
sig_u.connect(*slot_ptr);//版本A:编译器错误
//或
sig_u.connect(boost::ref(*slot_ptr));//版本B:警告,但编译并运行
//将插槽指针添加到插槽向量
槽向后退(槽向后退);
}
此代码(版本A)不可编译。它在boosts slot_template.hpp内部和connectSlot方法中标记的行处断开:

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'const Slot<FunSig>' (or there is no acceptable conversion)
1>          with
1>          [
1>              FunSig=void (const float &)
错误C2679:二进制“=”:未找到接受“const Slot”类型的右侧操作数的运算符(或没有可接受的转换)
1> 与
1>          [
1> FunSig=void(常量浮点&)
有趣的是,如果改用版本B,这段代码将编译并运行,即boost::ref将从插槽中传递。尽管在boost的singals2 auto_buffer.hpp中有一个编译器警告“带有可能不安全的参数的函数调用”,但此调用依赖调用方检查传递的值是否正确

那么,这里的实际问题是什么以及如何解决它呢?为什么它与boost::ref一起工作,为什么没有它它就无法编译

我甚至不确定整个设计思想是否有用。最初的想法是将整个信令/插槽内容隐藏在超类中,并将重点放在签名上(包括生命周期管理)


关于boost信号2的另一个问题:信号2连接()方法引用一个时隙。这是如何内部处理的。它是否使用连接的时隙的引用,或者它是一个时隙的复制品吗?这很重要,因为我的时隙处理动态分配的内存。

< P>我假定你是警告C499。这是微软C++标准库实现的一个特性,它警告你WH。从未使用可能不安全的参数编译过标准算法,例如,在此代码段中,调用方负责提供足够大小的
源代码
目标代码

int source[3] = { 1, 2, 3 };
int target[3];
std::copy(source, source + 3, target);
您不应该复制Boost.Signals2已经提供的功能:该库提供了对“插槽”的复杂的终身管理连接到一个信号,他们预见了这方面的一个非常精细的控制。此外,你失去了一个非常有趣的功能-Boost的线程安全。信号2:你需要管理线程安全的插入和从
slotVec\uu
中删除,这是一项非常重要的任务

我正在开发一个类似的抽象库,名为我自己,请查看
vex/functional/contracts
中的
abstract\u multicast\u delegate
abstract\u signal
。基于
signals2::signal
的实现可以在
vex/functional/implementation/bs2\u signal.h
中找到。然而,这仍然是个问题作为一个游乐场,我也在尝试其他的实现方式


编辑:抱歉,我不知道如何指向codeplex的hg存储库提示。我不得不删除链接,因为昨天以来发生了很多变化…

这个问题在不同的上下文中得到了回答


实际上,必须使用std::ref或boost::ref,因为boost::signals2 connect方法复制其参数。但是类槽是不可复制的,因为它是一个抽象类。因此,建议使用boost::ref,因为它使槽可复制。

首先,尝试将
槽类型
转换为
boost
插槽类型。第二,注意值语义和纯虚拟接口。第三,假设您的插槽类型是一个说“我有一个op()”的接口,
std::function
似乎更好。第四,智能指针中没有虚拟析构函数的抽象接口?@Yakk谢谢。这是什么意思“注意值语义…”connectSlot()和boost的connect()都将其参数作为指针/引用。但它们是否在内部按值存储参数?我不知道插槽是否在内部按值处理。B
int source[3] = { 1, 2, 3 };
int target[3];
std::copy(source, source + 3, target);