整合库时如何将类非静态成员函数用作回调函数?
问题描述
我正在整合两个独立库:一个是实现了Nelder-Mead方法的数值优化器,另一个是传感器校准库。优化器要求传入回调函数指针执行优化操作,但传感器库的回调是类的非静态成员函数,编译时会报错:error: invalid use of non-static member function。
以下是简化后的示例代码:
optimize.h
#pragma once double Optimizer( double (*func)(const double&), const double& arg) { return func(arg); }
testLib.h
#pragma once class Calibrator { public: double testFun(const double& arg); double doThing(); double x = 9.8; };
testLib.cpp
#include "testLib.h" #include "optimize.h" double Calibrator::testFun(const double& arg) { x *= arg; return x; } double Calibrator::doThing() { return Optimizer(testFun, 10); }
需要解决该问题,且尽量不通过彻底重构两个库的方式实现。
解决方案
方法1:静态包装函数+类实例指针
非静态成员函数隐含this指针,无法直接转换为普通函数指针。可以通过静态包装函数+类静态指针传递当前实例,间接调用成员函数:
修改testLib.h:
#pragma once class Calibrator { public: double testFun(const double& arg); double doThing(); double x = 9.8; private: static inline Calibrator* currentInstance = nullptr; static double wrapperFun(const double& arg); };
修改testLib.cpp:
#include "testLib.h" #include "optimize.h" double Calibrator::testFun(const double& arg) { x *= arg; return x; } double Calibrator::wrapperFun(const double& arg) { return currentInstance->testFun(arg); } double Calibrator::doThing() { currentInstance = this; return Optimizer(wrapperFun, 10); }
注意:多线程场景下需要加锁保护currentInstance,避免实例被覆盖。
方法2:修改优化器支持std::function(推荐)
如果允许对优化器库做微小改动,将函数指针替换为std::function,可以更优雅地处理成员函数:
修改optimize.h:
#pragma once #include <functional> double Optimizer(std::function<double(const double&)> func, const double& arg) { return func(arg); }
修改testLib.cpp的doThing方法:
double Calibrator::doThing() { return Optimizer([this](const double& arg) { return this->testFun(arg); }, 10); }
这种方式无需全局变量,支持lambda、成员函数、普通函数等多种回调形式,且多线程安全。
内容的提问来源于stack exchange,提问作者P_B
相关产品推荐
相关产品推荐

