2013-12-12 27 views
0

我尝试使用与C++ 11 “简单” 信号系统我使用了以下类: http://geekswithblogs.net/raccoon_tim/archive/2011/09/28/lambdas-and-events-in-c.aspxC++ 11信号制式

但我有一个问题(I使用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

向我们展示一些我们可以尝试编译的代码。 –

+0

除非您承诺使用这个“简单”信号系统,否则我会建议您使用更加无处不在的(经过测试的)库,例如boost信号2。 – 111111

+0

我已经修复了这个问题2,这是一个“完全重新编译”的问题! Thx您的意见... – Spectral

回答

1

A nswer 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捕获是很好的风格。似乎会给其他问题的人带来问题。

+0

仅供参考,您可以在lambda中捕获'this',但它只能通过值捕获,而不能通过引用捕获。必须保证指针保持有效,至少只要lambda仍然存在 –

+0

感谢HostileFork,我同意你的观点,我的目标是改进它一点,第一步是处理“void”,然后处理几个参数...但是对于两者都不知道如何? – Spectral

+0

@Spectral如果你真的想要写一个信号和插槽库,会有很多方法来攻击它,如果你想要走“ RREvent <>'和'RREvent '和'RREvent '您可以查看[variadic templates](http://www.cplusplus.com/articles/EhvU7k9E/)。您也可以定义一个函数类型,然后设计您的信号插槽机制将被参数化。虽然... – HostileFork

0

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

http://bitbucket.org/danielko/simplesignal

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

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

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

+0

非常感谢Daniel, 问题是,它不能用Visual Studio 2012进行编译。不支持可变参数模板! – Spectral