我有这张地图:
map<IEvent, EventHandler, IEventCompare>
EventHandler
被定义为typedef void (*EventHandler)(IEvent);
IEvent
是描述一般事件的类。
现在,我想向此映射添加一个函数,该函数接收CreationEvent
,该类继承了IEvent
。该函数的定义如下:
void onCreate(CreationEvent);
但是当我尝试将其添加到地图时,出现编译错误
E0167 argument of type "void (Engine::IObject::*)(Engine::CreationEvent)" is incompatible with parameter of type "Engine::EventHandler"
如果我尝试将其明确转换为EventHandler
:
E0171 invalid type conversion
我可以用onCreate
声明IEvent
,但是我想避免使用它,因为这将要求我假设事件的类型,而且定义不明确。
有没有办法做我尝试的事情?
IEvent:
/**
* Represents an Event, such as collision between 2 objects or click on an object.
*/
class IEvent
{
public:
IEvent(string name) { this->name = name; };
/**
* Copy constructor.
*/
IEvent(const IEvent& other) { this->name = other.name;};
string getName() const { return this->name; };
protected:
string name;
};
CreationEvent:
class CreationEvent : public IEvent
{
public:
CreationEvent();
std::chrono::time_point<std::chrono::system_clock> getCreateTime() const;
private:
std::chrono::time_point<std::chrono::system_clock> creationTime; /**< The creation time of this event.*/
};
注意:
一切都在命名空间Engine
中,并且映射在IObject
内部声明。
答案 0 :(得分:1)
如果我对您的想法正确,那么您想要:
ID_NF
的类型化事件。ID
的处理程序。考虑下一个示例。为简单起见,我使用event
代替了handler
,并将其放在事件类中。
此代码包含丑陋,泄漏,未经修改,不得在“产品”中使用。
std::vector
唯一棘手的部分是:
std::map
这里我们生成用于存储类型化的“回调”并使用多态性将这些类存储在std :: vector中的类,因为它们都是处理程序的子类。
建议-考虑使用智能指针而不是原始指针。另外,您可以将函数#include <iostream>
#include <vector>
//***********************************************************//
struct event;
struct handler
{
};
struct event_handler
{
event_handler(handler* receiver) : receiver_{ receiver } {}
handler* receiver_;
virtual void invoke(event& evt) = 0;
};
template <typename T, typename U>
struct event_handler_impl : event_handler
{
typedef void (T::* handler_function)(U&);
event_handler_impl(handler* receiver, handler_function function) :
event_handler{ receiver_ },
function_{ function } {}
void invoke(event& evt) {
T* typed_receiver = static_cast<T*>(receiver_);
U& typed_event = static_cast<U&>(evt);
(typed_receiver->*function_)(typed_event);
}
handler_function function_;
};
struct event
{
void subscribe(event_handler* hdlr)
{
//TODO: Check. Is double added?
handlers_.push_back(hdlr);
}
void sent()
{
for (auto& item : handlers_)
{
item->invoke(*this);
}
}
std::vector<event_handler*> handlers_;
};
//*****************************EXAMPLE***********************//
struct creation_event : public event
{
int creation_id{};
};
struct bar_handler : public handler
{
void handle_creation(creation_event& evt)
{
std::cout << "bar" << evt.creation_id << std::endl;
}
};
struct foo_handler : public handler
{
void handle_creation(creation_event& evt)
{
std::cout << "foo" << evt.creation_id << std::endl;
}
};
template<typename T, typename U>
void subscribe_to_event(U& evt, T* reciver, void (T::* handler_function)(U&))
{
evt.subscribe(new event_handler_impl<T, U>(reciver, handler_function));
}
int main()
{
creation_event evt;
bar_handler bar;
foo_handler foo;
subscribe_to_event(evt, &foo, &foo_handler::handle_creation);
subscribe_to_event(evt, &bar, &bar_handler::handle_creation);
evt.sent();
evt.creation_id = 1;
evt.sent();
return 0;
}
放入处理程序基类,以便删除第二个参数,并将“ this”传递给event_handler_impl-template <typename T, typename U>
struct event_handler_impl : event_handler