我希望编写一个函数,该函数使用double
函数的返回值但是/我想在函数调用期间选择这个双函数。我的想法是:
#include <iostream>
double linea(double a, double b, double x);
double parabola(double a, double b, double c, double x);
void konjgrad(double (*function)(void** params), void** params);
double linea(double a, double b, double x){
return a*x+b;
}
double parabola(double a, double b, double c, double x){
return a*x*x+b*x+c;
}
void konjgrad(double (*function)(void** params), void** params){
double d;
d=function(params);
std::cout<<d<<std::endl;
}
int main(){
konjgrad(linea(1.6,5.1,2.6));
konjgrad(parabola(2.4,3.1,4,2.6));
return 0;
}
但我陷入了指针的迷宫中。有谁有想法,如何解决问题?
答案 0 :(得分:4)
您可以使用variadic templates和perfect-forwarding来提供所需的灵活性,而无需任何额外的运行时间开销:
template <typename TF, typename... TArgs>
void konjgrad(TF&& f, TArgs&&... args)
{
double d;
d = std::forward<TF>(f)(std::forward<TArgs>(args)...);
std::cout<<d<<std::endl;
}
然后可以按如下方式调用 konjgrad
:
konjgrad(linea, 1.6, 5.1, 2.6);
konjgrad(parabola, 2.4, 3.1, 4, 2.6);
或者,您可以使用lambda expressions并将参数绑定的负担放在调用者身上:
template <typename TF>
void konjgrad(TF&& f)
{
double d;
d = std::forward<TF>(f)();
std::cout<<d<<std::endl;
}
然后可以按如下方式调用 konjgrad
:
konjgrad([]{ return linea(1.6, 5.1, 2.6); });
konjgrad([]{ return parabola(2.4, 3.1, 4, 2.6); });
答案 1 :(得分:0)
<强>被修改强> 基于Vittorio Romeo的评论,更新为传递向量作为const引用,并在 linea 和抛物线 API中添加必要的断言。
如果你想避免可变参数函数,这是一种天真的方法。由于您的功能界面已明确定义,您可以在 linea 和抛物线函数中传递double类型参数的矢量或数组。
#include <vector>
using namespace std;
double linea(const std::vector<double>& params)
{
assert(params.size() == 3 /*Linear 3 parameters required*/);
return params[0] * params[1] + params[2];
}
double parabola(const std::vector<double>& params)
{
assert(params.size() == 4 /*Parabola 4 parameters required*/);
return params[0] * params[3] * params[3] +
params[1] * params[3] +
params[2];
}
konjgrad 函数的一点修改版本,它现在通过函数指针从底层调用返回double值。请注意,第一个参数清楚地定义了功能界面。第二个参数是双精度矢量。
double konjgrad(double(*function)(const std::vector<double>&), const std::vector<double>& params)
{
return function(params);//returning value from here
}
最后,您应该如何调用上面定义的API。
int main(int argc, wchar_t* argv[])
{
std::vector<double> vals;
vals.push_back(1.6);
vals.push_back(5.1);
vals.push_back(2.6);
double v1 = konjgrad(linea, vals);
std::vector<double> parab;
parab.push_back(2.4);
parab.push_back(3.1);
parab.push_back(4.0);
parab.push_back(2.6);
double v2 = konjgrad(parabola, parab);
return 0;
}
希望这会有所帮助。