C ++复合函数调用和求值

时间:2018-01-05 21:00:38

标签: c++ c++11

我试图从另一个函数调用函数。我在main() abd中创建了两个向量,将它们传递给fun2()fun2调用fun1,参数为(4.0 -2.0*p, 5.0+3.0*p)fun1应该返回5*(4.0 -2.0*p)^2 + 4*(5.0+3.0*p)^2 + 14。这将导致函数p作为参数,将由行//Question评估:值3应该放在那里。但语法或方法并不完全正确。我该如何评估这样的复合函数?

#include<iostream>
#include<vector>

double fun1(double x1, double x2)
{
    double res1 = std::pow(x1,2.0)*5.0 + std::pow(x2,2)*4.0 + 14.0; 
    return res1;
}

double fun2(const std::vector<double> *v1, const std::vector<double> *v2, double(*f1)(double, double))
{
    double p, res2;
    res2 = fun1(((*v1)[0] + p*(*v2)[0]), ((*v1)[1] + p*(*v2)[1]) );
    return res2;
}

int main()
{
    double res3;
    std::vector<double> v1 = { 4.0,5.0 };
    std::vector<double> v2 = { -2.0,3.0 };
    res3 = fun2(&v1, &v2, &fun1)(3); //Question

    return 0;
}

更新

我正在尝试评估像fun2(fun1(3))这样的函数,这在python等语言中是可能的。

2 个答案:

答案 0 :(得分:1)

如果要维护调用语法

res3 = fun2(&v1, &v2, &fun1)(3); 

我建议使用lambda函数;

之类的东西
auto fun2 (const std::vector<double> *v1,
           const std::vector<double> *v2,
           double(*f1)(double, double))
   -> std::function<double(double)>
{
    return [&](double p)
     { return fun1(((*v1)[0] + p*(*v2)[0]), ((*v1)[1] + p*(*v2)[1])); };
}

从C ++ 14开始,你可以避免使用std::function类型和(简单地使用auto作为返回类型)直接返回lambda函数

auto fun2 (const std::vector<double> *v1,
           const std::vector<double> *v2,
           double(*f1)(double, double))
{
    return [&](double p)
     { return fun1(((*v1)[0] + p*(*v2)[0]), ((*v1)[1] + p*(*v2)[1])); };
}

关闭主题:考虑到你没有修改向量的计数,我建议将它们作为const引用传递;所以

auto fun2 (std::vector<double> const& v1,
           std::vector<double> const& v2,
           double(*f1)(double, double))
{
    return [&](double p)
     { return fun1(v1[0] + p*v2[0], v1[1] + p*v2[1]); };
}

称为

res3 = fun2(v1, v2, fun1)(3); 

答案 1 :(得分:0)

如果您尝试实现更高阶的函数,那么fun2()应该返回一个捕获所有参数的lambda,然后使用:

std::function<double(double)> fun2(const std::vector<double> *v1, const std::vector<double> *v2, double(*f1)(double, double))
{
    // Return a std::function that can accept parameter p as
    // argument and call f1 with v1, v2, and p.
    return [v1, v2, f1](double p) -> double
    {
       return f1(((*v1)[0] + p*(*v2)[0]), ((*v1)[1] + p*(*v2)[1]) );
    };
}

https://ideone.com/WhFwXU处查看它。