如何将类的非静态成员函数作为参数传递给成员函数?
解决类非静态成员函数作为函数参数传递的问题
你的代码报错的核心原因是:非静态成员函数和普通自由函数的签名不匹配。anotherFunction作为someClass的非静态成员函数,它的实际签名是bool (someClass::*)(unsigned) const(隐含了一个this指针参数),但baseFunction期望的是bool (&)(unsigned)类型的普通函数引用,两者类型完全不兼容,所以编译器会报错。
下面是几种可行的解决方案,你可以根据自己的需求选择:
方案1:使用Lambda表达式(C++11及以上)
Lambda是最直观且灵活的方式,通过捕获this指针,把成员函数包装成符合要求的可调用对象。这里有两种实现方式:
方式1a:用std::function修改baseFunction
#include <functional> class someClass { public: // 修改参数为std::function<bool(unsigned)>,兼容各种可调用对象 bool baseFunction(unsigned argument, std::function<bool(unsigned)> argumentFunction) const { return argumentFunction(argument); } bool anotherFunction(unsigned) const { // 你的业务实现 return true; } bool finalFunction(unsigned argument) const { // 捕获this,把成员函数包装成符合参数要求的lambda return baseFunction(argument, [this](unsigned val) { return this->anotherFunction(val); }); } };
方式1b:用模板让baseFunction兼容任意可调用对象
如果不想引入std::function的运行时开销,可以把baseFunction改成模板函数:
class someClass { public: // 模板参数接受任意可调用类型,适配lambda、bind对象等 template<typename Callable> bool baseFunction(unsigned argument, Callable argumentFunction) const { return argumentFunction(argument); } bool anotherFunction(unsigned) const { // 你的业务实现 return true; } bool finalFunction(unsigned argument) const { return baseFunction(argument, [this](unsigned val) { return this->anotherFunction(val); }); } };
方案2:使用std::bind绑定this指针(C++11及以上)
和Lambda类似,std::bind可以把成员函数和当前对象的this指针绑定,生成一个可调用对象。同样需要修改baseFunction的参数类型为std::function:
#include <functional> class someClass { public: bool baseFunction(unsigned argument, std::function<bool(unsigned)> argumentFunction) const { return argumentFunction(argument); } bool anotherFunction(unsigned) const { // 你的业务实现 return true; } bool finalFunction(unsigned argument) const { // 绑定this和成员函数,用placeholders::_1接收外部传入的参数 return baseFunction(argument, std::bind(&someClass::anotherFunction, this, std::placeholders::_1)); } };
方案3:将anotherFunction改为静态成员函数
如果anotherFunction不需要访问类的非静态成员变量或其他非静态成员函数,可以直接把它改成静态成员函数。静态成员函数没有隐含的this指针,签名和普通自由函数一致,就能直接传递给baseFunction:
class someClass { public: // 保持原函数签名不变 bool baseFunction(unsigned argument, bool (&argumentFunction)(unsigned)) const { return argumentFunction(argument); } // 改为静态成员函数,去掉隐含的this指针 static bool anotherFunction(unsigned) { // 你的业务实现(注意:不能访问类的非静态成员) return true; } bool finalFunction(unsigned argument) const { // 现在可以直接传递静态成员函数了 return baseFunction(argument, anotherFunction); } };
总结
- 如果需要访问类的非静态成员:优先选Lambda(代码更易读、维护性更好)或
std::bind - 如果不需要访问非静态成员:直接改成静态成员函数最省事,不需要修改
baseFunction的签名 - 模板版本的
baseFunction性能最优,避免了std::function的额外运行时开销
内容的提问来源于stack exchange,提问作者W. Verbeke
相关产品推荐
相关产品推荐

