【问题标题】:How to assign a lambda function to struct member, when the function must access other members?当函数必须访问其他成员时,如何将 lambda 函数分配给结构成员?
【发布时间】:2019-04-07 02:23:46
【问题描述】:

我想在我的对象中编写一个实用函数指针,该指针调用对象中的一组其他函数。该实用程序函数指针应使用默认功能进行初始化,但也可以覆盖。

这是我目前所拥有的:

struct GameState {
    void(*setup)()          = [](){};
    void(*handleInput)()    = [](){};
    void(*update)()         = [](){};
    void(*draw)()           = [](){};
    void(*run)() = [this]() { handleInput(); update(); draw(); };
}

编译器不喜欢在捕获我的 lambda 函数时使用this,并为该行吐出以下错误:

E0413 - “lambda []void ()->void”没有合适的转换函数 到“void (*)()”存在

C2440 '正在初始化':无法从 'GameState::' 到 '无效 (__cdecl *)(void)'

C2439 'GameState::run':无法初始化成员

【问题讨论】:

  • 可以对std::function 使用类型擦除,但是这会产生许多其他问题,使您的类不可复制和/或不可分配。这是XY problem。你真正的问题是什么?不,不是你要问的,如何使函数指针以这种方式工作。但是您认为解决方案的真正问题是使函数指针以这种方式工作。这是错误的解决方案。如果您解释您的真正问题是什么,我相信存在真正的解决方案。
  • 为什么不是普通的旧虚拟函数?
  • @n.m.我不知道 OP 的想法是什么,但我已经看到了像这样的 lambda 函数的用例。在某些情况下,可以使用 lambdas 来消除 if..else。例如,在 LazyInit 类中,get() 方法实际上可以是 lambda。在 C# 中比较常见,不知道是好还是坏
  • @MichaelVeksler 对 std::function 建议的回答达到了预期的结果。我不确定如何在不创建派生类/结构的情况下覆盖虚函数。为每个代码变体创建一个唯一的派生类似乎效率低下。
  • 是的,您需要创建一个派生类。就代码行而言,我不认为它效率低下。每班大约两行似乎并不过分。就运行时性能而言,它可能更有效。它也更灵活一些。

标签: c++ struct lambda function-pointers


【解决方案1】:

问题是类型不匹配。

void(*run)() = [this]() { handleInput(); update(); draw(); }; }

您正在将 lambda 分配给函数指针。 lambda 不是函数指针,实际上是覆盖operator() 的类的实例。此对象还会在您的 example 中捕获此内容。

void(*setup)() = [](){};

因为没有捕获而编译。当没有捕获时,就没有状态,lambda 可以被视为指针而不是类实例。

如果语言允许,你会喜欢类似的东西

// error
auto run  = [this]() { handleInput(); update(); draw(); };·

但在这种情况下不支持该语法。而且由于程序员不知道 lambda 对象的类型,所以没有办法写出它的类型。

相反,可行的是:

std::function<void()>run  = [this]() { handleInput(); update(); draw(); };

这不如使用 lambda 类型定义 run 高效,因为 std::function 很可能会将 lambda 存储在堆上。

【讨论】:

  • 您的建议似乎很有效。谢谢你的详细解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-01
相关资源
最近更新 更多