C++中如何调用结构体的成员函数指针?
问题解决:C++结构体成员函数指针的使用
C++完全支持结构体/类的成员函数指针,但它和普通全局函数指针是不同的类型——成员函数需要依赖类的实例(即this指针)才能调用,这也是你代码报错的核心原因。以下是具体的解决方法和原理:
1. 成员函数指针的正确声明与赋值
对于some_struct中的foo1、foo2这类非静态成员函数,它们的指针类型是:
int (some_struct::*)(int)
你需要明确指定类限定符来获取成员函数的地址,修正后的problem_function代码如下:
int problem_function(int x, bool a) { // 方式1:显式声明成员函数指针类型 int (some_struct::*func)(int) = a ? &some_struct::foo1 : &some_struct::foo2; // 方式2:用auto自动推导类型(更简洁) // auto func = a ? &some_struct::foo1 : &some_struct::foo2; // 必须绑定当前实例(this)才能调用成员函数指针 return (this->*func)(x); }
2. 为什么原代码报错?
- 原写法
a ? foo1 : foo2或&foo1没有明确类限定符,虽然编译器能推断是当前类的成员,但三元运算符要求两个操作数的类型完全一致,显式写出&some_struct::foo1才能明确类型,避免歧义。 - 成员函数指针调用时必须绑定实例:成员函数内部隐含
this参数,因此调用时必须通过this->*func或(*this.*func)的语法,把实例和函数指针绑定后才能传参调用。
3. 适配普通函数指针接口(如find_first)
如果需要将成员函数传递给接受普通函数指针的接口(比如你提供的find_first),由于成员函数指针和普通函数指针类型不兼容,有两种常用方案:
方案A:用std::function包装
修改find_first的参数类型为std::function,这样可以兼容捕获了this的lambda表达式:
#include <functional> // 调整接口参数类型 void* find_first(std::function<ExprToken*(ExprToken*)> cond) { // ... 原有逻辑 } // 在some_struct的成员函数中调用 void some_member() { // 用lambda捕获this,包装成员函数调用 find_first([this](ExprToken* tok) { return this->foo1(tok); // 或根据条件选择foo1/foo2 }); }
方案B:用静态成员函数转发
如果无法修改find_first的接口,可以把成员函数逻辑封装为静态成员函数,额外接收实例指针作为参数:
struct some_struct { int a; int foo1(int x) { return x * a; } int foo2(int x) { return x + a; } // 静态转发函数 static int foo1_static(some_struct* inst, int x) { return inst->foo1(x); } static int foo2_static(some_struct* inst, int x) { return inst->foo2(x); } void some_member() { // 选择对应的静态函数指针(普通函数指针类型) int (*func)(some_struct*, int) = a ? &some_struct::foo1_static : &some_struct::foo2_static; // 调用时传递this指针 func(this, 10); } };
内容的提问来源于stack exchange,提问作者Egemen Yalın
相关产品推荐
相关产品推荐

