lambda与/不捕获变量之间的签名差异? [英] Signature difference between lambda with/without captured variable?
问题描述
现在我正在玩C ++ 11,发现使用lambda作为sqlite的回调的以下问题。当在lambda内部捕获一个向量变量时,我得到一个错误,说明签名不匹配。不在lambda中使用该变量( []
而不是 [& ret]
,而不使用 ret
里面),它工作正常。
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);
这是我得到的错误:
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版本为gcc(XvidVideo.RU - GCC 4.6.1 i686
GCC version is "gcc (XvidVideo.RU - GCC 4.6.1 i686-pc-mingw32) 4.6.1 20110625 (prerelease)" on Windows.
为什么这会产生影响?
推荐答案
只有无记录的lambdas可以转换为函数指针,并且基于编译器诊断,您的 sqlite3_exec
指针 int(*)(void *,int,char **,char **)
。
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**)
.
quote§5.1.2[expr.prim.lambda] / 6
To quote §5.1.2[expr.prim.lambda]/6
没有lambda捕获的lambda表达式的闭包类型公共非虚拟非显式const转换函数到具有与闭包类型的函数调用运算符相同的参数和返回类型的函数的指针。
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.
这篇关于lambda与/不捕获变量之间的签名差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!