Signature difference between lambda with/without c

2019-04-28 23:14发布

问题:

I'm playing around with C++11 right now and found the following problem with using a lambda as callback to sqlite. When capturing a vector variable inside the lambda, I get an error saying that the signatures don't match. Without using that variable in the lambda ([] instead of [&ret], and not using ret inside), it works fine.

vector<SomeClass> ret;
char *err = nullptr;
int res = sqlite3_exec(db,
                       "some sql query, doesn't matter",
                       [&ret](void *unused, int argc, char **argv, char **columnName) -> int
                       {
                           ret.push_back(SomeClass());
                           return 0;
                       },
                       nullptr,
                       &err);

This is the error I get:

cannot convert 'TestClass::testMethod()::<lambda(void*, int, char**, char**)>' to 'int (*)(void*, int, char**, char**)' for argument '3' to 'int sqlite3_exec(sqlite3*, const char*, int (*)(void*, int, char**, char**), void*, char**)'

GCC version is "gcc (XvidVideo.RU - GCC 4.6.1 i686-pc-mingw32) 4.6.1 20110625 (prerelease)" on Windows.

Why does this make a difference?

回答1:

Only captureless lambdas can be converted to pointers to function, and, based on the compiler diagnostic, your sqlite3_exec expects such a pointer, int (*)(void*, int, char**, char**).

To quote §5.1.2[expr.prim.lambda]/6

The closure type for a lambda-expression with no lambda-capture 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.



回答2:

what about using the 1st argument for callback?

vector<SomeClass> ret;
char *err = nullptr;
int res = sqlite3_exec(db,
                       "some sql query, doesn't matter",
                       [](void *ctx, int argc, char **argv, char **columnName) -> int
                       {
                           static_cast<vector<SomeClass>*>(ctx)->push_back(SomeClass());
                           return 0;
                       },
                       &ret,
                       &err);


标签: lambda c++11