Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将成员函数作为回调参数传递给需要“typedef ed”自由函数指针的函数?_C++_Function Pointers_Member Function Pointers_Stdbind - Fatal编程技术网

C++ 如何将成员函数作为回调参数传递给需要“typedef ed”自由函数指针的函数?

C++ 如何将成员函数作为回调参数传递给需要“typedef ed”自由函数指针的函数?,c++,function-pointers,member-function-pointers,stdbind,C++,Function Pointers,Member Function Pointers,Stdbind,不可能有指向非静态成员函数的(非成员)函数指针。也不可能将函数指针指向绑定函数 请注意自由函数类型如何具有参数void*cbdata。您还没有显示您使用的API的文档,但我敢打赌API遵循一种常见的习惯用法,mg\u set\u request\u handler的第三个参数也是void*cbdata。如果我的假设是正确的,那么传递给注册的同一指针将在稍后传递给处理程序。它的目的是将数据(例如HttpServer实例)传递到回调中 例如: // typedef from library that

不可能有指向非静态成员函数的(非成员)函数指针。也不可能将函数指针指向绑定函数

请注意自由函数类型如何具有参数
void*cbdata
。您还没有显示您使用的API的文档,但我敢打赌API遵循一种常见的习惯用法,
mg\u set\u request\u handler
的第三个参数也是
void*cbdata
。如果我的假设是正确的,那么传递给注册的同一指针将在稍后传递给处理程序。它的目的是将数据(例如
HttpServer
实例)传递到回调中

例如:

// typedef from library that I cannot change
typedef int (*mg_request_handler)(mg_connection *conn, void *cbdata);

// this free function is for testing 
int get_handler_free(struct mg_connection* conn, void* cbdata) {
  //...
}

// this member function is what I want to use
int HttpServer::get_handler_member(struct mg_connection* conn, void* cbdata) {
  //...
}

// inside this member function, the callback param is needed
void HttpServer::start() {
  //...

  // this way doesn't work
  mg_request_handler get_handler = std::bind(&HttpServer::get_handler_member, this);
  mg_set_request_handler(ctx_, "/get", get_handler, nullptr);

  // this way works well
  mg_request_handler get_handler = &get_handler_free;
  mg_set_request_handler(ctx_, "/get", get_handler, nullptr);

  //...
}
mg_set_request_处理程序(ctx,“/get”,[](mg_连接*conn,void*cbdata){
断言(cbdata);
HttpServer&server=*静态广播(cbdata);
获取处理程序成员(conn、cbdata);
},这个);
如果
get\u handler\u member
具有非公共访问权限,则需要使用静态成员函数,而不是我在示例中使用的lambda。另外,
get\u handler\u成员
cbdata
参数现在可能没有用处,可以删除

请记住,只要注册了处理程序,就要保持
HttpServer
实例处于活动状态


另外,重新迭代:这取决于我对您展示的API的假设。仔细查阅文档。

无论如何旋转,都不能将成员函数用作指向非成员函数的指针。唯一的解决方法是使用
静态
成员函数,该函数将对象指针作为参数(或作为作为参数传递的结构的成员)获取然后调用非静态成员函数。我认为第三个参数是“用户数据”指针,您可以在其中传递指向对象的指针。我会担心lambda的生存期。但除此之外,我同意你的“一般”方法。@KevinAnderson无需担心。lambda没有捕获任何东西。@duong_dajgja是早期版本的遗留,不必要的复杂。我现在已经修好了。哦,这样我就可以绕过
服务器中的
cbdata
。获取处理程序成员(conn,cbdata)->
server.get\u handler\u成员(conn,nullptr)对吗?@duong_dajgja为什么不完全删除成员函数中的参数?您可以在指针中传递更多的数据,而不仅仅是
this
,但更好的选择可能是将任何数据作为
HttpServer
的成员保留。
mg_set_request_handler(ctx_, "/get", [](mg_connection *conn, void *cbdata) {
    assert(cbdata);
    HttpServer& server = *static_cast<HttpServer*>(cbdata);
    server.get_handler_member(conn, cbdata);
}, this);