如何在 C 11 中将 lambda 表达式存储为类的字段?

新手上路,请多包涵

我想创建一个类,客户端可以在其中存储一个像 []() -> void {} 这样的 lambda 表达式作为该类的一个字段,但我不知道该怎么做。 一个答案建议使用 decltype ,我尝试过但没有成功。这是一个 ideone源链接。以下是来源和结果:

 #include <cstdio>
auto voidLambda = []()->void{};

class MyClass {
public:
     decltype(voidLambda) t;
     MyClass(decltype(voidLambda) t) {
        this->t = t;
     }
};

int main() {
   MyClass([] {
      printf("hi");
   });
}

结果:

 prog.cpp: In constructor 'MyClass::MyClass(<lambda()>)':
prog.cpp:3:79: error: no matching function for call to '<lambda()>::__lambda0()'
prog.cpp:2:20: note: candidates are: <lambda()>::<lambda>(const<lambda()>&)
prog.cpp:2:20: note:                 <lambda()>::<lambda>(<lambda()>&&)
prog.cpp:3:88: error: no match for 'operator=' in '((MyClass*)this)->MyClass::t = t'
prog.cpp: In function 'int main()':
prog.cpp:5:27: error: no matching function for call to 'MyClass::MyClass(main()::<lambda()>)'
prog.cpp:3:48: note: candidates are: MyClass::MyClass(<lambda()>)
prog.cpp:3:14: note:                 MyClass::MyClass(const MyClass&)

有谁知道如何做到这一点?

原文由 user34537 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 609
1 个回答

如果您希望类成员成为 lambda 表达式,请考虑使用 std::function<> 包装器类型(来自 <functional> 标头),它可以包含任何可调用函数。例如:

 std::function<int()> myFunction = [] { return 0; }
myFunction(); // Returns 0;

这样,您就不需要知道 lambda 表达式的类型。您可以只存储一个适当函数类型的 std::function<> ,模板系统将为您处理所有类型。更一般地,任何适当签名的可调用实体都可以分配给 std::function<> ,即使该函子的实际类型是匿名的(在 lambda 的情况下)或非常复杂。

std::function 模板中的类型应该是与您要存储的函数相对应的函数类型。因此,例如,要存储一个接收两个 int 并返回 void 的函数,您将创建一个 std::function<void (int, int)> 。对于不带参数并返回 int 的函数,您可以使用 std::function<int()> 。在您的情况下,由于您想要一个不带参数并返回 void 的函数,因此您需要这样的东西:

 class MyClass {
public:
    std::function<void()> function;
    MyClass(std::function<void()> f) : function(f) {
        // Handled in initializer list
    }
};

int main() {
    MyClass([] {
        printf("hi")
    }) mc; // Should be just fine.
}

希望这可以帮助!

原文由 templatetypedef 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题