不同类成员函数加入函数指针数组的编译错误求助
嘿,我来帮你理清这个编译错误的根源,然后给出可行的解决方案!
错误原因分析
首先看你遇到的两个错误,本质都是同一个问题:非静态成员函数的指针类型和普通函数指针完全不兼容。
第一个错误
'&': illegal operation on bound member function expression
你尝试取&(this->Update)的地址,但Update是OtherClass的非静态成员函数,这类函数的指针类型是void (OtherClass::*)()——它需要绑定一个OtherClass对象才能调用(因为隐式携带this指针)。而你用this->试图绑定对象再取地址,这是非法的语法,成员函数指针的正确写法是&OtherClass::Update,但这又引出第二个问题。第二个错误
no instance of overloaded function std::vector...matches
当你写&Update时,编译器识别出这是void (OtherClass::*)()类型的指针,但你的std::vector<void (*)()>存储的是普通无参无返回的函数指针,两种类型完全不匹配,所以push_back拒绝接受这个参数。
解决方案
根据你的需求,有两种常见的解决思路:
方案1:把Update改为静态成员函数(如果不需要访问对象成员)
如果Update函数不需要访问OtherClass的非静态成员变量或函数,直接把它改成静态函数就可以解决问题:
// OtherClass.h 修改后 class OtherClass{ private: static void Update(); // 改为静态成员函数 public: OtherClass(); };
然后在构造函数里这样调用:
// OtherClass.cpp 修改后 OtherClass::OtherClass(){ Time::UpdateFuncs.push_back(&OtherClass::Update); }
静态成员函数不需要this指针,它的指针类型就是void (*)(),完美匹配你的vector类型。
方案2:用std::function捕获对象(如果需要访问对象成员)
如果Update必须访问OtherClass的非静态成员,那你需要调整vector的存储类型,改用std::function<void()>来包装成员函数调用:
首先修改SomeClass.h的vector定义:
// SomeClass.h 修改后 #include <vector> #include <functional> // 必须包含这个头文件 class SomeClass{ public: static std::vector<std::function<void()>> UpdateFuncs; };
然后在OtherClass的构造函数里,用lambda捕获当前对象的this指针,把成员函数调用包装成无参的可调用对象:
// OtherClass.cpp 修改后 OtherClass::OtherClass(){ Time::UpdateFuncs.push_back([this](){ this->Update(); }); }
⚠️ 注意:要确保当你调用vector里的函数时,这个OtherClass对象仍然存在,避免出现悬空指针导致未定义行为。
方案3:存储对象指针+成员函数指针(无STL依赖的方式)
如果你不想用std::function,可以选择存储对象指针和成员函数指针的配对:
首先修改SomeClass.h:
// SomeClass.h 修改后 #include <vector> #include <utility> // 用于std::pair // 前向声明OtherClass class OtherClass; class SomeClass{ public: static std::vector<std::pair<OtherClass*, void (OtherClass::*)()>> UpdateFuncs; };
然后在构造函数里添加配对:
// OtherClass.cpp 修改后 OtherClass::OtherClass(){ Time::UpdateFuncs.emplace_back(this, &OtherClass::Update); }
调用的时候需要这样遍历执行:
// 调用示例 for(auto& func_pair : SomeClass::UpdateFuncs){ // 用成员函数指针的调用语法:(对象指针->*成员函数指针)() (func_pair.first->*func_pair.second)(); }
总结
核心问题就是非静态成员函数需要绑定对象才能调用,它的指针类型和普通函数指针不兼容。根据你的业务需求选择对应的方案就可以解决编译错误啦!
内容的提问来源于stack exchange,提问作者Kay Hennig

