我正在为一个项目构建一个 pubsub 系统,我遇到了一个有趣的问题,即事件值在事件通知和事件调度之间发生变化。我在其中看到问题的事件是 MouseMoveEvent,它包含使用 glm::vec2() 的屏幕坐标(它具有双类型的 x 和 y 字段)。
template<class E>
void notify_event(std::shared_ptr<E> event) {
if (_auto_dispatch) {
dispatch<E>(event);
} else {
// inspecting values here gives expected coordinates:
// like: 168.684,284.547
debug<E>(event);
_dispatch_queue.push([&]() {
// when the lambda runs, the coordinates are major messed up
// like: -1.82767e+16,4.57398e-41
debug<E>(event);
dispatch<E>(event);
});
}
}
-1.82767e+16,4.57398e-41 坐标无论输入值如何。我最初使用引用来传递事件,然后尝试共享指针,但我得到的结果完全相同。立即调度事件没有任何问题,但我的项目需要我收集事件然后稍后调度,因为不同的系统在创建事件时将处于不同的“就绪”状态。
我觉得捕获的事件引用最终以某种方式指向垃圾内存,但我对 C++ 中的 lambda 的理解不够深入,不知道为什么会看到这个。
这是怎么回事,有什么办法可以解决这个问题?
最佳答案
似乎 lambda 将在 notify_event
函数返回后调用,这意味着参数 event
将超出范围并且引用将无效。
虽然确实存在应该通过引用传递(或捕获)共享指针的用例,但这似乎不是其中之一。按值捕获它,以便 lambda 将拥有自己的始终有效的共享指针(即使在其他情况下的最后一个实例已被销毁之后)。
关于c++ - C++ lambda 捕获的引用在 lambda 执行时具有不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51604377/