类成员std::array中成员函数指针及std::function调用问题
解决类成员函数指针/ std::function 存储与调用问题
咱们先从你最开始用std::array存成员函数指针的情况说起:
你定义的m_redChances是成员函数指针数组,这类指针和普通函数指针不一样——非静态成员函数必须依赖类的实例才能调用,因为它隐含了一个this指针参数。你之前写的m_redChances[0];只是获取了指针本身,并没有触发调用。
正确的调用方式需要结合当前类的实例(比如this指针),用成员指针调用操作符->*:
// 在Chance类的成员函数里调用 (this->*m_redChances[0])();
如果是在类外部调用,就需要用具体的对象实例,比如:
logic::Chance chanceObj; (chanceObj.*chanceObj.m_redChances[0])();
这里的括号很重要,因为->*和.*的优先级比函数调用()低,必须用括号明确执行顺序。
再来说你后来改用std::function的版本:
你当前的代码有两个问题:
- 你只是获取了
std::function对象,但没有触发调用动作; - 成员函数
fun1、fun2的签名是void(),但你定义的std::function类型是void(Foo&),两者不匹配,直接赋值&Foo::fun1其实是隐式转换了,但调用时需要传入对象实例。
针对你的需求,有两种常见的解决方式:
方式一:调整std::function类型并绑定实例
如果希望调用时不需要额外传对象,可以把std::function的类型改成void(),然后在构造函数里用lambda捕获this,或者用std::bind绑定当前实例:
struct Foo { std::array<std::function<void()>, 3> funArray; Foo() { // 用lambda捕获this,直接绑定当前实例 funArray[0] = [this](){ this->fun1(); }; funArray[1] = [this](){ this->fun2(); }; // 或者用std::bind // funArray[0] = std::bind(&Foo::fun1, this); // funArray[1] = std::bind(&Foo::fun2, this); } void fun1() { std::cout << "fun1\n"; } void fun2() { std::cout << "fun2\n"; } std::function<void()> getFunction(int i) { return funArray[i]; } }; int main() { Foo foo; // 现在获取后直接调用即可 foo.getFunction(0)(); std::cin.get(); }
方式二:保持std::function类型,调用时传入实例
如果你想保留void(Foo&)的类型(比如支持传入不同的Foo实例调用),那调用时必须传入对象:
struct Foo { std::array<std::function<void(Foo&)>, 3> funArray; Foo() { // 直接赋值成员函数指针,因为void(Foo&)和成员函数的签名匹配(隐含this参数) funArray[0] = &Foo::fun1; funArray[1] = &Foo::fun2; } void fun1() { std::cout << "fun1\n"; } void fun2() { std::cout << "fun2\n"; } std::function<void(Foo&)> getFunction(int i) { return funArray[i]; } }; int main() { Foo foo; // 调用时传入foo实例 foo.getFunction(0)(foo); std::cin.get(); }
这样就能正确执行存储在std::array里的成员函数了。
内容的提问来源于stack exchange,提问作者JohnDoe
相关产品推荐
相关产品推荐

