我正在尝试在 libuv 上包装一个 C++ 层,并使用 lambda 作为回调函数。但是 gcc 出错了。
这是缩小版:
#include <uv.h>
class Test {
public:
void on_conn(uv_stream_t *server, int status) { }
void test() {
uv_tcp_t server;
auto err = uv_listen((uv_stream_t*)&server,
100,
[this] (uv_stream_s *server, int status) -> void {
this->on_conn(server,status);
});
}
};
Test t;
libuv中的相关声明是:
# define UV_EXTERN /* nothing */
struct uv_stream_s { ... };
typedef struct uv_stream_s uv_stream_t;
typedef void (*uv_connection_cb)(uv_stream_t* server, int status);
UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
g++ 给出的错误:
$ g++ --version
g++ (GCC) 6.1.1 20160501
<<--ERROR--{reformatted}-->>
t.cpp:15:7: error: cannot convert
‘Test::test()::<lambda(uv_stream_s*, int)>’ to
‘uv_connection_cb {aka void (*)(uv_stream_s*, int)}’
for argument ‘3’ to ‘int uv_listen(uv_stream_t*, int, uv_connection_cb)’
}));
这里到底坏了什么?有什么方法可以使这项工作正常进行吗?
更新:
更有趣.. lambda 主体中的这个做了一些事情;第一个电话有效,第二个电话无效。
int cfunc( void cb() );
class Test {
public:
void d(){}
void test() {
cfunc( [=] () {});
cfunc( [=] () { this->d(); });
//cfunc( [this] () { });
//cfunc( [&this] () { });
}
};
t.cpp:10:34: error: cannot convert ‘Test::test()::<lambda()>’ to ‘void (*)()’ for argument ‘1’ to ‘int cfunc(void (*)())’
cfunc( [=] () { this->d(); });
最佳答案
捕获 lambda 不能转换为函数指针,只有非捕获可以:
//Lambda captures 'this', and so cannot be converted to function pointer
[this](uv_stream_s *server, int status) -> void {
this->on_conn(server,status);
}
关于c++ - 将 C++ lambda 传递给 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37771271/