Pass function as parameter to integrate object using lambda
用于教育目的
我有一个函数集成,它以 std::function 作为参数。
1 2 3 4 5 6 7 8 9 | 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 调用此函数
1 2 3 | 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 函数。
我想知道我是否可以使语法对用户更容易并更接近数学方式。
所以我更希望用户只需要输入:
1 2 | 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 中实现这一点吗?
这正是 Boost.Lambda 的设计目的。语法如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <iostream> #include <vector> #include #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 << '\ ' // a?‘a?‘a?‘a?‘a?‘a?‘a?‘a?‘a?‘a?‘a?‘a?‘a?‘a?‘ // to delay invocation of func ); } |
这是否比 C 11 lambda 语法更好完全取决于您。
请注意,由于 C 14 和一些功能滥用,我们实际上也可以准确地编写您想要的表达式:
1 2 3 4 5 | auto x = _1; auto sin(decltype(_1) ) { return bind(static_cast<double(*)(double)>(std::sin), _1); } |
有了它,我们可以做到:
1 2 3 | std::for_each(v.begin(), v.end(), std::cout << x * sin(x) - x * x << '\ '); |
这将打印出与原始示例完全相同的内容。只是......更神秘。