有没有办法在C++复合函数?

Is there a way to compound functions in C++?

本文关键字:复合函数 C++ 有没有      更新时间:2023-10-16

一般问题:

如果有两个对象AB,则具有各自的功能f_A(arg list)f_B(arg list)

创建具有 f_A(...( 和 f_B(...( 复合函数的对象 C 的最佳方法是什么? 例如:f_C() = f_A() + f_B() or f_C() = f_A(f_B())

是否可以重载"+"运算符,以便我们可以创建对象 C 做类似的事情?

auto object_c = object_a + object_b

这是我的代码示例:

class GaussianKernel : public Kernel {
public:
GaussianKernel(double sigma) : m_sigma(sigma), m_scale(1) {}
double covarianceFunction(
double   X,
double   Y
)
{
double result;
result = m_scale  *  exp(-norm(X - Y) / (m_sigma*m_sigma));
return result;      
}

GaussianKernel operator+(const GaussianKernel& b) {
/*Here I would like to overload the + operator such that 
I can create a kernel from two others kernels, 
I mean with a covariance function compound of the previous ones 
*/
}
private:
double m_sigma;
double m_scale;
};

谢谢。

给定两个方法f_Af_B,您可以通过例如使用 lambda 返回其他方法的总和f_C

auto f_C = [](/*param*/){ return f_A(/*param*/) + f_B(/*param*/); };
auto sum_result = f_C(param);

要获得复合方法,它将是这样的:

auto f_C = [](/*param*/){ return f_B( f_A(/*param*/)); };
auto compound_result = f_C(param);

PS:我知道这并不直接适用于你的例子,仍然试图找出你到底想做什么。

我会从这样的原型解决方案开始:

class FooKernel : public Kernel {
public:
FooKernel (std::function<double(double, double)> fun) : fun_(fun) {}
double covarianceFunction(
double   X,
double   Y
) const {
return fun_(X, Y);
}
template<class T>
auto operator+(const T &b) const {
return FooKernel([b, this](double X, double Y){
return this->covarianceFunction(X, Y) + b.covarianceFunction(X, Y);
});
}
private:
std::function<double(double, double)> fun_;
};    

class GaussianKernel : public Kernel {
public:
GaussianKernel(double sigma) : m_sigma(sigma), m_scale(1) {}
double covarianceFunction(
double   X,
double   Y
) const 
{
double result;
result = m_scale  *  exp(-norm(X - Y) / (m_sigma*m_sigma));
return result;      
}
template<class T>
auto operator+(const T &b) const {
return FooKernel([b, this](double X, double Y){
return this->covarianceFunction(X, Y) + b.covarianceFunction(X, Y);
});
}
private:
double m_sigma;
double m_scale;
};

不再使用 lambda,但现在根据需要使用 Pure 函数。

稍后我会尝试删除std::function,因为它可能会对性能产生相当大的影响。相反,我会将FooKernel变成一个类模板,用于存储可按值调用的模板。

我会建议Kernel的另一个子类:

class CompoundGaussianKernel : public Kernel {
public:
CompoundGaussianKernel(GaussianKernel const& kernel1, GaussianKernel const& kernel2) 
: m_kernel1(kernel1), m_kernel2(kernel2) 
{}
double covarianceFunction(double X, double Y)
{
return m_kernel1.covarianceFunction(X, Y) + m_kernel2.covarianceFunction(X, Y);
// or any other composition than "+"
}
private:
GaussianKernel m_kernel1;
GaussianKernel m_kernel2;
};

我建议不要在类内部定义operator+,而是将其定义为自由函数。

CompoundGaussianKernel operator+(GaussianKernel const& kernel1, GaussianKernel const& kernel2)
{
return CompoundGaussianKernel(kernel1, kernel2);
}