带/不带捕获变量的lambda之间的签名差异?

带/不带捕获变量的lambda之间的签名差异?,lambda,c++11,Lambda,C++11,我现在正在使用C++11,发现使用lambda作为sqlite的回调存在以下问题。在lambda中捕获向量变量时,我得到一个错误,表示签名不匹配。如果不在lambda中使用该变量([]而不是[&ret],并且不在内部使用ret),它就可以正常工作 vector<SomeClass> ret; char *err = nullptr; int res = sqlite3_exec(db, "some sql query, doesn't m

我现在正在使用C++11,发现使用lambda作为sqlite的回调存在以下问题。在lambda中捕获向量变量时,我得到一个错误,表示签名不匹配。如果不在lambda中使用该变量(
[]
而不是
[&ret]
,并且不在内部使用
ret
),它就可以正常工作

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);
vectorret;
char*err=nullptr;
int res=sqlite3_exec(db,
“一些sql查询,没关系”,
[&ret](void*unused,int-argc,char**argv,char**columnName)->int
{
ret.push_back(SomeClass());
返回0;
},
nullptr,
&错误);
这是我得到的错误:

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**)'
无法将参数“3”的“TestClass::testMethod()::”转换为“int(*)(void*,int,char**,char**)”转换为“int sqlite3_exec(sqlite3*,const char*,int(*)(void*,int,char**,char**),void*,char**)”
GCC版本在Windows上是“GCC(XvidVideo.RU-GCC 4.6.1 i686-pc-mingw32)4.6.1 20110625(预发布)”


为什么会有不同?

只有无捕获lambda可以转换为函数指针,并且根据编译器诊断,您的
sqlite3\u exec
需要这样一个指针,
int(*)(void*,int,char**,char**)

引用§5.1.2[解释原始lambda]/6

没有lambda捕获的lambda表达式的闭包类型具有一个公共非虚拟非显式const转换函数,该函数指向与闭包类型的函数调用运算符具有相同参数和返回类型的函数指针


使用回调的第一个参数怎么样

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);
vectorret;
char*err=nullptr;
int res=sqlite3_exec(db,
“一些sql查询,没关系”,
[](void*ctx,int-argc,char**argv,char**columnName)->int
{
静态强制转换(ctx)->向后推(SomeClass());
返回0;
},
&ret,
&错误);

有道理。我只是想知道我是否能用捕获的变量以任何方式解决这个问题。(在这种特殊情况下,我当然可以使用SQLite的回调变量来实现我的目的)。“ANDIKEL,我猜您必须走这么多C++库回调的方式:一个非成员或静态成员函数,根据一些代码<虚空*/COD>来确定真正调用的是什么。”
sqlite3\u exec
允许我向回调传递一个
void*
,我只是天真地认为使用C++11可以更轻松地完成这项工作。我正在使用visual studio 2010编译器尝试同样的方法,它不喜欢任何形式的lambda。。。有人知道这是否是VS2010 impl中的已知错误吗?