如何将非静态成员函数赋值给C++普通函数指针?
解决方案
非静态成员函数调用时依赖对象的this指针,但你定义的sdf是普通函数指针,无法自动携带这个上下文。由于不能修改两者的函数签名,这里提供两种适配方案:
方案一:静态包装函数 + 全局实例指针
适合单实例场景,通过静态指针绑定目标MeshInput对象,用静态包装函数中转调用:
#include <tgmath.h> // 假设tg::pos3来自相关头文件 class MeshInput; class VoxelGrid { private: double (*sdf)(tg::pos3 const&); public: // 提供设置sdf的接口 void setSdf(double (*func)(tg::pos3 const&)) { sdf = func; } }; class MeshInput { public: static MeshInput* currentInstance; // 静态指针绑定目标实例 double sdfFromMesh(tg::pos3 const& point) { // 这里是你的原有实现逻辑 return 0.0; } // 静态包装函数,匹配sdf的函数签名 static double sdfWrapper(tg::pos3 const& point) { return currentInstance->sdfFromMesh(point); } }; // 初始化静态成员 MeshInput* MeshInput::currentInstance = nullptr; // 使用示例 int main() { MeshInput mesh; MeshInput::currentInstance = &mesh; // 绑定当前实例 VoxelGrid voxelGrid; voxelGrid.setSdf(&MeshInput::sdfWrapper); // 赋值包装函数 return 0; }
方案二:线程局部存储适配多实例/多线程
如果需要同时使用多个MeshInput实例或在多线程环境下运行,把静态指针改成线程局部存储,避免实例冲突:
#include <tgmath.h> class MeshInput; class VoxelGrid { private: double (*sdf)(tg::pos3 const&); public: void setSdf(double (*func)(tg::pos3 const&)) { sdf = func; } }; class MeshInput { public: static thread_local MeshInput* currentInstance; // 线程局部存储的实例指针 double sdfFromMesh(tg::pos3 const& point) { return 0.0; } static double sdfWrapper(tg::pos3 const& point) { return currentInstance->sdfFromMesh(point); } }; // 初始化线程局部静态成员 thread_local MeshInput* MeshInput::currentInstance = nullptr; // 多线程使用示例(伪代码) #include <thread> void threadFunc(MeshInput* mesh) { MeshInput::currentInstance = mesh; VoxelGrid grid; grid.setSdf(&MeshInput::sdfWrapper); // 后续调用grid的sdf相关逻辑 }
注意事项
- 方案一的全局指针在多实例场景下会互相覆盖,仅适合单实例或单线程的简单场景。
- 方案二的线程局部存储需要C++11及以上标准支持,每个线程可以独立绑定不同的
MeshInput实例。 - 确保在调用
sdf之前已经正确绑定了currentInstance,否则会触发空指针访问错误。
内容的提问来源于stack exchange,提问作者conixtract
相关产品推荐
相关产品推荐

