我尝试使用带有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':未声明的标识符
感谢您的帮助
答案 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()
)将阻止信号传递给插槽的所有者。
希望它简单易读,易于理解;可变参数模板可以处理任意数量的参数,无需专门化。