c ++ 11信号系统

时间:2013-12-12 12:52:52

标签: c++ events c++11 lambda signals

我尝试使用带有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':未声明的标识符

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

回答1:

您文章中的RREvent1Arg不是通用信号/广告位系统。它不是以通用的方式编写的。它并不是为了容纳void而编写的,这并不奇怪,因为除了1(给定名称)之外它不处理许多参数也就不足为奇了。

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

回答2:

Offhand我不确定在“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捕获是好的风格。似乎在其他问题上给人们带来了问题。

答案 1 :(得分:0)

我写了这个“简单的信号库”,我用它来做一堆项目:

http://bitbucket.org/danielko/simplesignal

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

它实现的是信号/槽语义;当你连接时,只要你想接收来自信号的通知,就会得到一个你需要保持活着的插槽。销毁插槽(或在其上调用disconnect())将阻止信号传递给插槽的所有者。

希望它简单易读,易于理解;可变参数模板可以处理任意数量的参数,无需专门化。