首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用void*和void**灵活的函数调用

使用void*和void**灵活的函数调用
EN

Stack Overflow用户
提问于 2017-01-24 19:25:51
回答 2查看 143关注 0票数 0

我希望编写一个函数,该函数使用double函数的返回值,但是/并且我想在函数调用期间选择这个双精度函数。我的想法是:

代码语言:javascript
复制
#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;
}

但我陷入了指针的迷宫中。有没有人知道如何解决这个问题?

EN

回答 2

Stack Overflow用户

发布于 2017-01-24 19:33:28

您可以使用和引入所需的灵活性,而无需任何额外的运行时开销:

代码语言:javascript
复制
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

代码语言:javascript
复制
konjgrad(linea, 1.6, 5.1, 2.6);    
konjgrad(parabola, 2.4, 3.1, 4, 2.6);

或者,您可以使用,并将绑定参数的负担放在调用者身上:

代码语言:javascript
复制
template <typename TF>
void konjgrad(TF&& f)
{
    double d;
    d = std::forward<TF>(f)();
    std::cout<<d<<std::endl;
}

然后,可以按如下方式调用konjgrad

代码语言:javascript
复制
konjgrad([]{ return linea(1.6, 5.1, 2.6); });    
konjgrad([]{ return parabola(2.4, 3.1, 4, 2.6); });
票数 4
EN

Stack Overflow用户

发布于 2017-01-24 21:17:23

基于维托里奥·罗密欧的评论编辑了,更新以传递向量作为常量引用,并在直线和抛物线API中添加了必要的断言。

如果你想避免不同的函数,这里有一个很简单的方法。由于你的函数接口定义得很清楚,你可以在你的linea和parabola函数中传入双精度类型参数的向量或数组。

代码语言:javascript
复制
#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函数,它现在通过函数指针从底层调用返回双精度值。请注意,第一个参数明确定义了函数接口。第二个参数是双精度向量。

代码语言:javascript
复制
double konjgrad(double(*function)(const std::vector<double>&), const std::vector<double>& params)
{
    return function(params);//returning value from here
}

最后,这里是您应该如何调用上面定义的API。

代码语言:javascript
复制
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;

}

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41827038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档