Difference in type of lambda when using [] and [this]

浪尽此生 提交于 2021-01-27 11:53:39

问题


I have a class db_interface. And defined a lambda type:

typedef void (*db_interface_lambda)();

When I create lambda in class in such way: [](){ /* do something */ }, it has good type (db_interface_lambda), but when I use [this](){ /* do something */ }, the compiler starts to shout at me.

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

How to solve that problem? What is the correct type?


回答1:


Because lambdas are only implicitly convertible to function pointers if and only if they do not capture anything.

§5.1.2 [expr.prim.lambda] p6

The closure type for a lambda-expression with no lambda-capture ([] is empty) has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator.

Btw, what you typedef'd there is a function pointer, not a lambda type. Lambda expressions have a unique, unnamed, nonunion class type. You can not name them.

§5.1.2 [expr.prim.lambda] p3

The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type




回答2:


You're trying to call something that wants a function pointer. A captureless lambda can be converted to a function pointer automatically, but once you write [this] it ceases to be captureless - you're capturing this, so it's an error.

The solution is to change the type to be a std::function, not a pointer to a function. std::function erases the type of the "functor" it "wraps" so you can still pass a function pointer as well as a lamba with a capture.




回答3:


Lambdas that do not capture anything are essentially free functions, and thus they are convertible to ordinary function pointers.

Lambdas that do capture are essentially full classes, and they cannot simply be converted to a free-function pointer. (A capturing lambda is really essentially the same predicate functor class that you would have written in C++ before we had lambdas.)

Either version of lambda is convertible to std::function<void()>, which is what the mapped type of your map should be.



来源:https://stackoverflow.com/questions/8539924/difference-in-type-of-lambda-when-using-and-this

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!