将函数作为参数传递以使用 lambda 集成对象
Pass function as parameter to integrate object using lambda
出于教育目的
我有一个函数 integrate,它接受一个 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++ 中实现吗?
这正是 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');
这将打印与原始示例完全相同的内容。只是...更神秘。
出于教育目的
我有一个函数 integrate,它接受一个 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++ 中实现吗?
这正是 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');
这将打印与原始示例完全相同的内容。只是...更神秘。