c++11信号系统



我尝试使用C++11的"简单"信号系统。我使用以下类:http://geekswithblogs.net/raccoon_tim/archive/2011/09/28/lambdas-and-events-in-c.aspx

但我有一个问题(我使用Visual Studio 2012):

问题描述

我不能创建这样的事件:

RREvent1Arg<void> testEvent;

"void"不是参数类型!!

我尝试过"模板专业化",比如:

template<typename T1, typename T2> class Signaler {};
template<> class Signaler<T1> {};
template<> class Signaler<void> {};

但我遇到了一些编译问题:

错误C2065:"T1":未声明的标识符

感谢您的帮助

答案1:

您文章中的RREvent1Arg不是通用的信号/插槽系统。它不是以一种笼统的方式写的。它没有被编写为适应void也就不足为奇了,就像它不处理除1(给定名称)之外的许多参数也就不足为奇一样。

请注意,它将回调处理程序定义为typedef std::function<void (T1)> Func;,然后尝试定义类似void Call( T1 arg )的内容。不能在源代码中声明像C++中的void foo( void arg )这样的函数,也不允许模板创建这些函数。有一些方法可以使用重载来解决这个问题,但也有一些方法使用变量参数等。

答案2:

顺便说一句,我不太确定在"this"上使用lambda的捕获功能的规则是什么,尤其是当它被封装为std::function时。因为这很令人困惑,我建议将其保存到另一个局部变量中,并通过值捕获:

static RREvent1Arg<int> testEvent;
class MyClass
{
 int a;
 void MyMethod()
 {
   MyClass *mc = this;
   testEvent += [=mc](int) { mc->SignalReceived(); };
 }
 void SignalReceived()
 {
   this->a = 10;
 }
};

但那只是我。也许this的捕捉是一种很好的风格。似乎在其他问题上给人们带来了问题。

我写了这个"简单信号库",用于一系列项目:

http://bitbucket.org/danielko/simplesignal

它不处理返回值的累积,因为我认为这个用例不够常见,不足以保证额外的复杂性。

不过,它所实现的是信号/插槽语义;当你连接时,你会得到一个插槽,只要你想从信号中接收通知,你就需要保持它的活动状态。销毁插槽(或在插槽上调用disconnect())将停止向插槽所有者传递信号。

希望它足够简单易懂;可变模板可以处理任意数量的参数,不需要专门化。

最新更新