传递函数作为参数使用lambda集成对象

时间:2015-04-10 01:03:45

标签: c++ math syntax

出于教育目的

我有一个函数集成,它将std :: function作为参数。

double calculus::integralSimple(std::function<double(double)> fn, double begin, double end)
{
    double integral = 0; 
    for (long double i = begin; i < end; i += _step)
    {
        integral += fn(i) * _step;  // _step defined in class 
    }
    return integral;
}

目前我正在使用

从main.cpp调用此函数
calculus cl;
std::cout << cl.integralSimple(calculus::identity,0,1);
std::cout << cl.integralSimple([](double x) { return x*x; }, 0, 1);

其中identity是calculus.h中定义的静态函数,另一个使用lambda函数。

我想知道我是否可以让用户更容易理解语法,更接近数学方式。 所以我更喜欢用户只需键入:

std::cout << cl.integralSimple( x*x ,0,1); // Always take a function of this form 
std::cout << cl.integralSimple( x*sin(x) - x*x ,0,1);

有没有办法在C ++中实现这个目标?

1 个答案:

答案 0 :(得分:1)

这正是Boost.Lambda的设计目标。语法如下所示:

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

const double PI  =3.141592653589793238463;

double func(double v) { return std::sin(v); } // to avoid having to
                                              // cast std::sin

int main()
{
    using namespace boost::lambda;

    std::vector<double> v = {0, PI / 4, PI / 2, PI};

    std::for_each(v.begin(), v.end(),
        std::cout << _1 * bind(func, _1) - _1 * _1 << '\n'
    //                    ↑↑↑↑↑↑↑↑↑↑↑↑↑↑
    //                    to delay invocation of func
    );
}

是否更好比C ++ 11 lambda语法更完全取决于你。

请注意,由于C ++ 14和一些滥用功能,我们实际上也可以准确地编写您想要的表达式:

auto x = _1;

auto sin(decltype(_1) ) {
    return bind(static_cast<double(*)(double)>(std::sin), _1);
}

有了这个,我们可以做到:

std::for_each(v.begin(), v.end(),
    std::cout << x * sin(x) - x * x << '\n');

这将打印与原始示例完全相同的内容。只是......更加隐秘。