C++事件调度员 - 回调铸造问题
我正在冒险使用Visual Studio 2022中使用C ++ 17创建EventDisPatcher。基本上,我存储了一个字符串(ID)来识别事件,并通过registerevent()方法在vector中识别vector中的回调(lambda,function或a类)。 。 然后,我需要调用将事件传递给参数的dispatchevent()方法。此事件将事件ID作为参数接收。在内部,dispatchevent()方法循环找到具有相应ID的事件,并执行先前存储的回调,将事件传递给回调。 当使用通用事件时,一切都可以完美。 (只需评论DocustomeVents()方法中的所有内容;
问题
在创建从通用事件派生的事件时,在此示例中,Customevent将无法执行铸件并发出以下错误:
错误c2440:< function-style-cast>':无法从'initializer list''转换为'eventprops':line 41
在此 - >
m_eventprops.push.push_back( EventProps(ID,回调);
到目前为止,我所看到的都无法帮助我解决这个问题
。
我一直在研究铸造,但是 请
按照以下代码
#include <iostream>
#include <string>
#include <vector>
#include <functional>
#define DEBUG(x) std::cout << x << std::endl;
#define BIND(fn) [this](auto...args) -> decltype(auto) { return this->fn(args...); }
class Event
{
public:
std::string Id;
Event(std::string id) : Id(id) { }
std::string ToString() { return "Event(id=" + Id +")"; }
};
class CustomEvent : public Event
{
public:
std::string Message;
CustomEvent(std::string id, std::string message) : Event(id), Message(message) { }
std::string ToString() { return "CustomEvent(id=" + Id + ", message=" + Message + ")"; }
};
struct EventProps
{
public:
std::string Id;
std::function<void(Event)> Callback;
EventProps(std::string id, std::function<void(Event)> callback) : Id(id), Callback(callback) { }
};
class EventDispatcher
{
private:
std::vector<EventProps> m_EventProps;
public:
template<typename T>
void RegisterEvent(std::string id, std::function<void(T)> callback)
{
m_EventProps.push_back(EventProps(id, callback));
}
void DispatchEvent(Event event)
{
for (int i = 0; i < m_EventProps.size(); i++)
{
EventProps props = m_EventProps[i];
if(props.Id == event.Id) props.Callback(event);
}
}
};
void globalCallback(Event e) { DEBUG("[Global] " + e.ToString()); }
void customGlobalCallback(CustomEvent ce) { DEBUG("[Global] " + ce.ToString()); }
class Application
{
public:
EventDispatcher dispatcher;
Application()
{
doEvents();
doCustomEvents(); // Nothing works here
}
void doEvents()
{
dispatcher.RegisterEvent<Event>("event_0", [](Event e) { DEBUG("[Lambda] " + e.ToString()); });
dispatcher.RegisterEvent<Event>("event_1", globalCallback);
dispatcher.RegisterEvent<Event>("event_2", BIND(Application::OnEvent));
dispatcher.DispatchEvent(Event("event_0"));
dispatcher.DispatchEvent(Event("event_1"));
dispatcher.DispatchEvent(Event("event_2"));
}
void doCustomEvents()
{
dispatcher.RegisterEvent<CustomEvent>("custom_0", [](CustomEvent e) { DEBUG("[Lambda] " + e.ToString()); });
dispatcher.RegisterEvent<CustomEvent>("custom_1", customGlobalCallback);
dispatcher.RegisterEvent<CustomEvent>("custom_2", BIND(Application::OnCustomEvent));
dispatcher.DispatchEvent(CustomEvent("custom_0", "Hi custom 0"));
dispatcher.DispatchEvent(CustomEvent("custom_1", "Hi custom 1"));
dispatcher.DispatchEvent(CustomEvent("custom_2", "Hi custom 2"));
}
void OnEvent(Event e) { DEBUG("[Application::OnEvent] " + e.ToString()); }
void OnCustomEvent(CustomEvent ce) { DEBUG("[Application::CustomEvent] " + ce.ToString()); }
};
int main()
{
Application app;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这个问题可能处于人们通常会关闭的问题的边缘,但是MSVC在这里提供了一个真正无用的错误消息,使您的生活更加艰难。 (您可能想尝试升级编译器; godbolt.org上的最新MSVC给出了更多有用的信息。)
问题与
以下几行有关。
dispatcher.registerevent&lt; customevent&gt;
采取第二个类型的参数std :: function&lt; void(customevent)&gt;
,然后继续使用它来尝试构建EventProps
。但是,EventProps想要的构造函数是std :: function&lt; void(event)&gt;
。编译器无法将仅接受CustomeVent
s的函数转换为接受 all all事件
s的函数。您需要模板
eventprops
本身,或调整registerevent
,以将类型t
的函数转换为一个功能,以获取所有event
s。This question is probably on the edge of what people would normally close, but MSVC is making your life harder by giving a really useless error message here. (You might want to try upgrading your compiler; recent MSVC on godbolt.org give much more helpful messages.)
The problem is with
and the following lines.
dispatcher.RegisterEvent<CustomEvent>
takes a second argument of typestd::function<void(CustomEvent)>
and then proceeds to use it to try to construct anEventProps
. However what the constructor of EventProps wants is astd::function<void(Event)>
. There is no way for the compiler to convert a function that only acceptsCustomEvent
s into a function that accepts allEvent
s.You need to either template
EventProps
itself, or adaptRegisterEvent
to convert a function taking events of typeT
into a function taking allEvent
s.