【发布时间】:2019-10-05 12:20:28
【问题描述】:
在 C++ 中实现一个简单的玩具事件循环,我遇到了一个问题。我有一个接口(抽象类)Event,它由不同类型的事件(键盘、异步调用等)实现。在我的示例中,SomeEvent 是 Event 的实现。
enum class EventType {
SOME_EVENT = 0,
};
class Event {
public:
virtual ~Event() {}
virtual EventType get_event_type() = 0;
};
class SomeEvent: public Event {
public:
SomeEvent(): m_event_type(EventType::SOME_EVENT) {}
void bar() { std::cout << "hello" << std::endl; }
EventType get_event_type() { return this->m_event_type; }
public:
EventType m_event_type;
};
EventHandler 是一个 lambda,它接受 Event,对它做一些事情,但什么也不返回。我有一张与事件类型相关联的EventHandler 地图。 (地图在这个 MWE 中指向 EventHandler,但在我最初的实现中,它当然指向一个向量)
typedef std::function<void(std::unique_ptr<Event>)> EventHandler;
std::map<EventType, EventHandler> event_handlers;
template <class T>
void add_event_handler(
EventType event_type,
const std::function<void(std::unique_ptr<T>)> &event_handler) {
event_handlers[event_type] = event_handler; // Does not compile
}
当我使用inject_event 注入事件时,我只是在映射中获取事件处理程序并使用事件作为参数调用它。
void inject_event(std::unique_ptr<Event> event) {
event_handlers[event->get_event_type()](std::move(event));
}
问题来自这张地图的通用性。它应该包含一个采用Event 的处理程序,但我想在采用接口的lambda 和采用该接口的实现的lambda 之间没有继承链接,所以it fails 因为它不能分配std::function<void(SomeEvent)>到 ``std::function` 类型的变量。
我一直在为此摸不着头脑,我的 C++ 生锈了,根本不是最新的。你会怎么做?语言中是否存在允许我以通用方式指定 lambda 的模式或功能?尝试在EventHandler 定义中使用auto,但似乎不允许。
【问题讨论】:
-
如果您想使用函数指针来访问它,您似乎无法在 lambda 中捕获任何内容:请参阅stackoverflow.com/questions/28746744/…
-
@PabloOliva 真的是我的问题吗?我没有使用函数指针。我的理解是 std::function 不是函数指针,您可以使用捕获 lambda。