编写内联函数作为参数传递

C++ Writing inline function to pass as argument

本文关键字:参数传递 函数      更新时间:2023-10-16

我正在为一个个人图书馆编写一套学习算法。学习算法需要两样东西,一个可供探索的输入空间,以及一种将一个解决方案与另一个解决方案进行比较的方法。定义输入空间是最基本的数据传输,但是我很难将评级函数传递给它。

目前我的问题代码看起来像这样:

RankineGenerator generator(tempHotWater,tempColdWater);
int variablesSize = 2;
Range minMaxVaporizer = { tempColdWater,tempHotWater };
Range minMaxCondenser = { tempColdWater,tempHotWater };
Range minMax[] = {minMaxVaporizer, minMaxCondenser};
auto phi = [&generator] ( double * heatExchangerTemps ) -> double
{
generator.updateHeatExchangeTemps(heatExchangerTemps[0], heatExchangerTemps[1]);
generator.runSim();
return generator.getSpecificWork()/(generator.getColdWaterRelativeMass()+generator.getHotWaterRelativeMass());
};
Twiddle twiddle(variablesSize,phi,minMax,0.001);

我的构造函数头看起来像:

Twiddle(int size, double(*phi)(double*), Range minMax[], double minRatioDeltaPhi);

其中"phi"lambda函数是我试图传递给算法"twiddle"的内容

不一定是lambda函数,任何内联函数都可以。

关注点:

学习算法往往是计算密集型的,所以快速的解决方案比简单的解决方案更可取。

传递的函数需要某种方式从声明它的作用域访问一些信息。

学习算法需要具有通用性。传递特定问题的数据不是一个选项,我需要能够即插即用任何问题。理想情况下,构造函数应该采用如下形式:

constructor( nVars, ratingFunction(vars[nVars]), ranges[nVars], minImprovementSpeed)

更新:看来我引起了一些混乱。我的歉意。

首先,我使用术语内联表示在程序中间编写的函数,而不是作为一个独立的实体。不必与同名关键字有任何关系。

其次,我要做的是传递一个可以访问一些本地数据的函数。例如:

double(*phi)(double*) = [](double* heatExchangerTemps) { /*do something*/ };
Twiddle twiddle(variablesSize,phi,minMax,.001);

结构头:

Twiddle(int size, double (*phi)(double*) , Range minMax[], double minRatioDeltaPhi);

可以编译,但不能访问对象"generator"。但是,当我尝试在lambda函数中捕获"生成器"对象时:

double(*phi)(double*) = [&generator](double* heatExchangerTemps) { /*do something*/ };

auto phi = [&generator] ( double * heatExchangerTemps ) -> double { /*do something*/ };

出现错误。

我可以这样做:

double(*phi)(double*) = [](double* myArray)
{
    Generator generator(/*stuff*/);
    // do something
};

但是,每次调用该函数时,都会创建一个新的"Generator"类对象。考虑到这个函数可能被调用1000多次,这并不理想。再加上现在"Twiddle"算法需要特定于Generator构造函数的信息,这违背了拥有通用算法的全部目的。

理想情况下,我需要能够访问函数内部的局部对象(在本例中为生成器),并将该函数作为构造函数的泛型参数传递。

它也不一定是一个lambda函数,这只是我第一次想到的

经过几个小时的摸索,我发现了这个:

std::function<double(double*)> phi = [&generator] ( double * heatExchangerTemps ) -> double
{ /*do someting*/ };
Twiddle twiddle(variablesSize,phi,minMax,1000000);

带构造函数头:

Twiddle(int size, std::function<double(double*)> phi, Range minMax[], double maxResolution);

我不确定这是不是最好的答案,但它似乎很有效。

基本上我的lambda函数符合类型std::function<double(double*)>,这允许我保持lambda捕获能力,同时允许我的构造函数理解它接收的内容。