给std::function赋值类成员函数OnEvent出现匹配错误的求解
编译报错原因与解决方案
报错根因
提示没有与这些操作数匹配的“=”运算符的编译错误,本质由两个核心问题共同导致:
- 语法使用错误:
OnEvent是类的非静态成员函数,在类作用域内直接写函数名OnEvent,会被编译器判定为缺少必要参数的无效函数调用,不会自动生成可赋值的函数指针;必须显式使用取地址语法&Layer::OnEvent才能拿到对应的成员函数指针,当前写法本身就不满足语法要求。 - 签名完全不匹配:即便修正语法写对了成员函数地址,非静态成员函数的实际签名和
std::function<void(const Event&)>要求的可调用类型也不一致——非静态成员函数会隐含携带Layer* this作为第一个参数,完整函数类型是void(Layer*, const Event&),和std::function期望的、不需要类实例就能直接调用的void(const Event&)类型有本质差异,自然无法完成赋值。
可选解决方案
根据OnEvent是否需要访问类实例的成员信息,选择对应写法即可:
- 如果
OnEvent不需要访问类的非静态成员变量/成员方法,直接将OnEvent修饰为静态成员函数:
static void OnEvent(const Event& e);
此时函数签名和普通自由函数完全一致,构造函数内可以直接执行m_Callback = &Layer::OnEvent;完成赋值。
- 如果
OnEvent需要访问当前Layer实例的成员信息,就需要将当前类实例绑定到可调用对象上,两种等价写法都可以:- 使用
std::bind绑定this指针:// 构造函数内的赋值语句 m_Callback = std::bind(&Layer::OnEvent, this, std::placeholders::_1); - 使用lambda表达式捕获this指针,可读性更强:
// 构造函数内的赋值语句 m_Callback = [this](const Event& e) { this->OnEvent(e); };
- 使用
注意:使用上述绑定this的写法时,要保证回调触发时当前Layer实例没有被销毁,否则会出现悬垂指针触发未定义行为。
内容的提问来源于stack exchange,提问作者Nicky。
相关产品推荐
相关产品推荐

