VS2015下将Button::track_添加到callbacks向量失败问题求助
你遇到的核心问题是非静态成员函数指针和std::function<void()>的类型不匹配,下面我会一步步帮你分析并给出解决方案:
错误原因
Button::track_是一个非静态成员函数,它的实际签名是void (Button::*)()——这类函数必须依附于一个Button类的实例才能调用(隐含了this指针参数),但你的callbacks向量是std::vector<std::function<void()>>,要求的是不需要任何参数的可调用对象,直接传递&Button::track_自然会类型不匹配,导致添加失败。
解决方案
根据track_是否需要访问当前Button实例的成员,有两种处理方式:
1. 如果track_不需要访问实例成员:改为静态成员函数
如果track_里没有用到this或者类的非静态成员,直接把它声明为静态函数即可:
// buttons.h class Button: public Texture { public: void track(); static void track_(); // 改为静态成员 }; // buttons.cpp void Button::track() { Events::add_handler(&Button::track_); // 现在类型匹配了 } void Button::track_() { // 你的实现代码 }
2. 如果track_需要访问当前Button实例:绑定this指针
如果track_必须操作当前Button对象的成员,就需要把this指针和成员函数绑定在一起,转换成无参数的可调用对象。推荐两种方式:
方式A:使用std::bind
#include <functional> // 需要包含这个头文件 void Button::track() { Events::add_handler(std::bind(&Button::track_, this)); }
std::bind会把this指针和成员函数打包成一个不需要参数的可调用对象,完美匹配std::function<void()>的要求。
方式B:使用lambda表达式(更简洁直观)
void Button::track() { Events::add_handler([this]() { this->track_(); }); }
lambda可以直接捕获当前的this指针,内部调用track_,同样能生成符合要求的可调用对象。
额外检查
别忘了确认Events::add_handler的实现是正确的,它应该接收cb类型的参数并添加到callbacks向量中:
// events.cpp #include "events.h" std::vector<cb> callbacks; void Events::add_handler(cb func) { callbacks.push_back(func); }
这样修改后,Button::track()就能成功把track_(绑定了实例的版本)添加到callbacks里,Events::invoke_all调用时也能正确执行所有回调函数了。
内容的提问来源于stack exchange,提问作者Xtravagant

