c++ - C++ lambda 捕获的引用在 lambda 执行时具有不同的值

标签 c++ c++14

我正在为一个项目构建一个 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/

相关文章:

c++ - 赋值期间双重值变化

c++ - 您的计算机缺少 api-ms-win-core-synch-l1-2-1.dll

c++14 - 如果没有源代码,请使用 C++14 进行类型推导

c++ - 从模板类型而不是参数获取转发类型

c++ - SFINAE:static_assert 与 std::enable_if

c++ - 在类内的 union 内访问 map 会出现段错误

c++ - 可以使用 gcc 中的多个对齐属性来保证缓存行分离吗?

c++ - 花括号初始化列表和无符号类型

c++ - Qt 更新 QGraphicsScene 中的 QPixmapItem

c++ - 变量模板模板?