【发布时间】:2016-01-13 22:26:13
【问题描述】:
当触发事件(按键、鼠标等)时,我的应用程序将调用已为该事件注册的委托函数。
下面是实现。我正在尝试使“调用”函数 (()) 成为可变参数模板,以便可以将任何参数传递给它。但是我目前的设置低于它是不可能的。
有什么想法可以在这个设计中使用可变参数模板来实现吗?
编辑更改的代码
template <typename... params>
class EventDelegate
{
public:
typedef std::function<int(params...)> EDelegate;
EventDelegate(EDelegate delegate) : delegate(delegate)
{
}
int operator()(params...) const
{
return delegate(params...);
}
private:
EDelegate delegate;
};
// Not valid because template params are not specified. But each EventDelegate can take different params
std::unordered_multimap<int, EventDelegate> evtRegistry;
// Example
class Foo
{
public:
int onLeftClick(GUID sender, Point pos);
int onKeyDown(char key);
};
// Usage
...
evtRegistry[1] = EventDelegate(std::bind(&Foo::onLeftClick, myFoo, std::placeholders::_1, std::placeholders::_2));
evtRegistry[2] = EventDelegate(std::bind(&Foo::onKeyDown, myFoo, std::placeholders::_1));
事件处理:
LRESULT CALLBACK Win32App::wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
auto registeredCmps = evtRegistry.equal_range(EVT_INIT);
for (auto iter = registeredCmps.first; iter != registeredCmps.second; iter++)
iter->second();
}
break;
case WM_DESTROY:
{
auto registeredCmps = evtRegistry.equal_range(EVT_EXIT);
for (auto iter = registeredCmps.first; iter != registeredCmps.second; iter++)
iter->second(someParam, someOtherParam);
}
break;
...
【问题讨论】:
-
不清楚你想如何调用
EventDelegate而不知道要传递哪个参数... -
@Jarod42 哎呀,这是一个错字。我现在就修。那是我之前的实现
-
尚不清楚在遍历 evtRegistry 中的元素时如何区分事件。在不知道模板实例化的情况下如何调用函数?
-
你希望如何使用
evtRegistry[x]? -
@Jarod42 请参阅编辑以了解事件处理。注意 evtRegistry 是
unordered_multimap
标签: c++ templates variadic-templates