这有点难以描述,所以请耐心等待。我有两个独立的库,我正在尝试将它们结合起来。一个库是数值优化器(目前已实现Nelder Mead 优化器),另一个库是传感器校准库。优化器库需要用户指定并传递一个指向回调函数的指针来“优化”。传感器库有一个通用传感器类来存储各种传感器的校准数据(每个传感器一个类),并且需要调用此优化器并传递回调。但是,由于回调函数是传感器类的非静态成员,因此它会抛出“错误:无效使用非静态成员函数”之类的错误。
下面是一组非常简单的文件,作为我正在尝试做的事情的基本示例:
#pragma once
double Optimizer( double (*func)(const double&),
const double& arg)
{
return func(arg);
}
#pragma once
class Calibrator
{
public:
double testFun(const double& arg);
double doThing();
double x = 9.8;
};
#include "testLib.h"
#include "optimize.h"
double Calibrator::testFun(const double& arg)
{
x *= arg;
return x;
}
double Calibrator::doThing()
{
return Optimizer(testFun,
10);
}
如何解决这种情况,最好不要通过做一些古怪的事情(例如将优化器作为传感器校准类的一部分)来完全重构代码?
因为你似乎能够修改库,
Optimizer
必须修复:
旧的C兼容方式
double Optimizer(double (*func)(void* /*userdata*/, double),
void* userdata,
double arg)
{
return func(userdata, arg);
}
然后
double Calibrator::doThing()
{
return Optimizer(+[](void* calibrator, double d) {
return static_cast<Calibrator*>(calibrator)->testfunc(d);
}, this, 10);
}
C++ 方式,无类型擦除,带模板
template <typename F>
requires (std::invocable<F, double>
&& std::is_convertible_v<std::invoke_result_t<F, double>, double>)
double Optimizer(F f, double arg)
{
return f(arg);
}
或使用
std::function
/std::move_only_function
/function_ref
进行类型擦除
double Optimizer(std::function<double>(double) f, double arg)
{
return f(arg);
}
并且,对于他们两个来说,那么
double Calibrator::doThing()
{
return Optimizer([this](const double& d) {
return this->testfunc(d);
}, 10);
}