使用[]和[this]时lambda类型的差异

jac*_*web 3 c++ lambda c++11

我有一个类db_interface.并定义了一个lambda类型:

typedef void (*db_interface_lambda)();
Run Code Online (Sandbox Code Playgroud)

当我以这种方式在类中创建lambda:[](){ /* do something */ }它具有良好的类型(db_interface_lambda),但是当我使用时[this](){ /* do something */ },编译器开始对我大喊大叫.

cannot convert ‘db_interface::db_interface(std::ifstream&)::<lambda()>’ to ‘std::map<std::basic_string<char>, void (*)()>::mapped_type {aka void (*)()}’ in assignment
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题?什么是正确的类型?

Xeo*_*Xeo 8

因为lambdas只能隐式转换为函数指针,当且仅当它们不捕获任何东西时.

§5.1.2 [expr.prim.lambda] p6

没有lambda-capturelambda表达式的闭包类型(为空)有一个公共的非虚拟非显式const转换函数,用于指向具有与闭包类型的函数调用操作符相同的参数和返回类型的函数.[]

顺便问一下,你typedef有什么功能指针,而不是lambda类型.Lambda表达式具有唯一的,未命名的,不连续的类类型.你不能命名他们.

§5.1.2 [expr.prim.lambda] p3

的类型的λ-表达(这也是封闭的对象的类型)是一个唯一的,不连无名类类型


Fle*_*exo 7

你试图调用想要一个函数指针的东西.无捕获的lambda可以自动转换为函数指针,但是一旦你编写[this]它就不再是无法捕获的 - 你正在捕获this,所以这是一个错误.

解决方案是将类型更改为a std::function,而不是指向函数的指针.std::function擦除它"包装"的"仿函数"的类型,这样你仍然可以传递函数指针以及带捕获的lamba.


Ker*_* SB 6

不捕获任何东西的Lambda本质上是自由函数,因此它们可以转换为普通函数指针.

Lambda表达式是捕获基本上是满类,它们不能简单地转换成自由函数指针.(捕获lambda实际上与我们在使用lambdas之前用C++编写的谓词仿函数类相同.)

lambda的任何一个版本都可以转换为std::function<void()>,这就是你的地图的映射类型应该是什么.

  • *state-less*和*free*函数是不同的东西,`struct x {void operator()(){}};`显然是无状态的,不是自由函数,而是函数类.正如@awoodland所指出的那样,一个没有捕获的lambda可以被*转换为一个类似签名的自由函数,但这远远不是*本质上是一个自由函数.lambda*本质上是一个函子(函数类) (2认同)