问题
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