- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在用 C++ 实现一个简单的玩具事件循环时,我遇到了一个问题。我有一个接口(interface)(抽象类)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
是一个接受 Event
的 lambda ,用它做一些事情并且什么都不返回。我有 EventHandler
的 map 关联到事件类型。 ( map 指向此 MWE 中的 EventHandler
,但在我最初的实现中,它当然指向一个 vector )
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
注入(inject)事件时,我只是在 map 中获取事件处理程序并使用事件作为参数调用它。
void inject_event(std::unique_ptr<Event> event) {
event_handlers[event->get_event_type()](std::move(event));
}
问题来自这张 map 的通用性。它应该持有一个接受 Event
的处理程序但我想在采用接口(interface)的 lambda 和采用该接口(interface)的实现的 lambda 之间没有继承链接,所以 it fails因为它不能分配 std::function<void(SomeEvent)>
到 ``std::function` 类型的变量。
我一直在摸不着头脑,我的 C++ 生锈了,根本不是最新的。你会怎么做?语言中是否存在允许我以通用方式指定 lambda 的模式或功能?尝试使用 auto
在 EventHandler
定义,但似乎不允许。
最佳答案
好吧,C++ 的趋势是更喜欢静态多态性而不是动态多态性(实际上,静态或编译时一切都真的......);在你的情况下 - 你不能在运行时发生意外事件类型。
因此,也许您可以忘记示例中的大部分代码,并尝试基于 std::variant
的代码。 :
EventType
- 只需使用 std::variant::index()
在事件上获取可能的事件类型中的数字类型索引;或者更好 - 根本不要使用它,您的事件类型模板可能就足够了。class Event
和 class SomeEvent : Event
,你会得到 using Event = std::variant<events::Keyboard, events::Foo, events::Some>
.也许你会有 namespace events {
class Base { void bar() { /* ... */ } };
class Foo : class Base { /* ... */ };
}
所有事件都继承自 Base
(但不是虚拟的)。Event
不需要显式存储或读取它的类型 - 它总是知道(除非你主动删除类型)。Event*
的,你可以通过 Event
s 按值或按移动引用。所以不再std::unique_ptr
类不匹配。至于你的 lambda,它很可能变成:
void inject_event(Event&& event) {
std::visit(event_handlers,event);
}
与 event_handler
作为visitor .
现在 - 的确,您不能总是逃避动态多态性;有时你可以,但你工作的组织/公司太迟钝/笨拙,不允许这种情况发生。但是,如果您能做到这一点,可能会省去很多麻烦。
关于c++ - C++ 中的 Lambda 通用性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58248222/
我想使用JOGL图书馆,我想在linux和windows上使用它......在linux上编译的项目可以在windows上运行吗?如果我想为 Windows 编译它,我是否必须更改包含的库? 问候,彼
在用 C++ 实现一个简单的玩具事件循环时,我遇到了一个问题。我有一个接口(interface)(抽象类)Event它由不同类型的事件(键盘、异步调用……)实现。在我的示例中 SomeEvent是Ev
这些列表之间有什么区别。 ArrayList test = new ArrayList(); ArrayList test2= new ArrayList(); 或者在这两类之间。 class tes
对于我的 JavaFX UI,我实现了一个类 ObservableProperties延伸 java.util.Properties并能够监听某些属性的变化(特别是 UI 的本地化文本)。 它工作得很
我是一名优秀的程序员,十分优秀!