如何正确将类方法作为std::function参数传入?
问题:将类成员函数作为
std::function<void(void)>参数传入WebServer的on方法 我是C++新手,在用WebServer库时遇到语法问题——想把类方法作为std::function<void(void)>类型的参数传给WebServer的on方法,但多次尝试都编译失败。我想让on方法的参数指向WebServerInterface类的handleRootPageRequest方法,试过直接赋值成员函数指针、用std::mem_fn等方式,都不行,求正确写法。
相关代码
class WebServer { public: typedef std::function<void(void)> THandlerFunction; void on(const Uri& uri, THandlerFunction fn); // ... 其他成员 }; // ... class WebServerInterface { public: WebServerInterface() {}; void begin() { WebServer::THandlerFunction fhandleRootPageRequest = &WebServerInterface::handleRootPageRequest; // 无法编译 webServerCPP.on("/", fhandleRootPageRequest); } void handleRootPageRequest() { webServerCPP.send(200, "text/html", "<!doctype html> <html> <head> <body> <div> <h1>Hello World</h1> </div> </body> </html>"); } private: WebServer webServerCPP; };
尝试过的写法与编译错误
// 写法1:直接赋值成员函数指针 WebServer::THandlerFunction fhandleRootPageRequest = &WebServerInterface::handleRootPageRequest; // 错误:无法将类型“void (WebServerInterface::*)()”转换为非标量类型“WebServer::THandlerFunction”(别名“std::function<void()>”) // 写法2:使用std::mem_fn WebServer::THandlerFunction fhandleRootPageRequest = std::mem_fn(&WebServerInterface::handleRootPageRequest); // 错误:无法将类型“std::_Mem_fn<void (WebServerInterface::*)()>”转换为非标量类型“WebServer::THandlerFunction”(别名“std::function<void()>”) // 写法3:强制转换std::mem_fn的结果 WebServer::THandlerFunction fhandleRootPageRequest = (WebServer::THandlerFunction) std::mem_fn(&WebServerInterface::handleRootPageRequest); // 错误:没有匹配的函数用于调用“std::function<void()>::function(std::_Mem_fn<void (WebServerInterface::*)()>)”
正确实现方式
类成员函数必须依赖对象实例才能调用,因此需要把当前对象实例和成员函数绑定后,才能转换成无参数的std::function<void()>,以下是三种可行写法:
方法1:Lambda表达式(最直观推荐)
在begin方法中用Lambda捕获当前对象的this指针,内部直接调用成员函数:
void begin() { webServerCPP.on("/", [this]() { handleRootPageRequest(); }); }
方法2:使用std::bind
通过std::bind将成员函数与当前对象实例绑定,需要包含<functional>头文件:
#include <functional> void begin() { WebServer::THandlerFunction fhandleRootPageRequest = std::bind(&WebServerInterface::handleRootPageRequest, this); webServerCPP.on("/", fhandleRootPageRequest); }
方法3:显式用std::function包装绑定结果
本质和方法2一致,只是明确指定std::function类型:
#include <functional> void begin() { WebServer::THandlerFunction fhandleRootPageRequest = std::function<void()>(std::bind(&WebServerInterface::handleRootPageRequest, this)); webServerCPP.on("/", fhandleRootPageRequest); }
内容的提问来源于stack exchange,提问作者james-h
相关产品推荐
相关产品推荐

