C++移动成员函数实现后std::function绑定错误求助
问题解决:非静态成员函数地址与std::bind的正确用法
问题根源
非静态成员函数自带隐藏的this指针,因此不能直接将其地址作为普通函数指针传递,必须绑定对应的类实例才能正常调用;使用std::bind时,必须明确传入实例(指针或引用)并正确指定参数占位符,否则会触发参数数量不匹配的错误。
方案1:正确使用std::bind + std::function
假设你的类定义和接收函数对象的run函数如下:
头文件 type.h
namespace Tom { class Car { public: void drive(int speed); }; }
实现文件 type.cpp
#include "type.h" #include <iostream> void Tom::Car::drive(int speed) { std::cout << speed << " "; }
主程序正确写法
#include <iostream> #include <functional> #include "type.h" void run(std::function<void(int)> func) { func(50); func(100); } int main() { Tom::Car my_car; // 绑定类实例指针和成员函数,std::placeholders::_1对应后续传入的speed参数 auto bound_drive = std::bind(&Tom::Car::drive, &my_car, std::placeholders::_1); run(bound_drive); return 0; }
关键:std::bind的第一个参数是成员函数的地址,第二个参数是类实例的指针(或用std::ref(my_car)传递引用),占位符_1表示调用时传入的第一个参数会传递给drive的speed参数。
方案2:不使用std::function的实现
如果不想依赖std::function,可以用两种原生C++写法:
子方案2.1:Lambda表达式+模板函数
修改run为模板函数,支持任意可调用对象:
#include <iostream> #include "type.h" // 模板函数,兼容所有可调用类型 template<typename Callable> void run(Callable func) { func(50); func(100); } int main() { Tom::Car my_car; // Lambda捕获类实例,直接调用成员函数 run([&my_car](int speed) { my_car.drive(speed); }); return 0; }
这种写法简洁直观,无需额外绑定,直接通过lambda捕获实例并转发参数。
子方案2.2:成员函数指针模板
直接传递类实例和成员函数指针:
#include <iostream> #include "type.h" // 模板函数,接收类实例和成员函数指针 template<typename T> void run(T& obj, void (T::*drive_func)(int)) { // 成员函数指针调用语法:(对象.*函数指针)(参数) (obj.*drive_func)(50); (obj.*drive_func)(100); } int main() { Tom::Car my_car; run(my_car, &Tom::Car::drive); return 0; }
这种写法完全不依赖标准库的函数绑定工具,直接利用C++原生的成员函数指针语法。
内容的提问来源于stack exchange,提问作者Senor Maldona
相关产品推荐
相关产品推荐

