Owe*_*enM 5 c c++ matlab lambda function-binding
在matlab中,人们可以写:
S = @(x,y) x^2+y^2-1
G = @(x) S(x,1);
Run Code Online (Sandbox Code Playgroud)
如果我有一个期望单参数函数的函数,我可以做到以上几点.我怎么能用c/c ++做到这一点?
我有一个库函数(来自CGAL库),它希望作为一个参数,一个函数本身只有一个参数.理想情况下,我有一个class(SphericalHarmonics),我希望有一个成员函数,它接受一个参数.所以我有:
FT SphericalHarmonics::distFunction(Point_3 p)
Run Code Online (Sandbox Code Playgroud)
(注意这FT是一个类似的类型double)但当然我尝试的时候
SphericalHarmonics *sh = new SphericalHarmonics(1);
Surface_3 surface(sh->distFunction, Sphere(ORIGIN,2.));
Run Code Online (Sandbox Code Playgroud)
this也被视为参数,我的distFunction函数是一个双参数函数,并抛出一个错误.
请注意,这可以通过全局变量来解决,即
SphericalHarmonics *sh;
FT dist_function(Point_3 p) {
return sh->distFunction(p);
}
main() {
sh = new SphericalHarmonics(1);
Surface_3 surface(dist_function);
}
Run Code Online (Sandbox Code Playgroud)
但是,这真的不理想.我想要一种没有全局变量的方法,因为能够拥有一个可以轻松地与CGAL库集成的类函数会好得多.
提前致谢!
[更新]
@安迪警车:我想你std::bind和lambda解决方案,但似乎仍然运行到错误,至于参数的个数.
当main我在使用代码时:
SphericalHarmonics *sh = new SphericalHarmonics(cInit, numL, symm);
auto fxn = std::bind(&SphericalHarmonics::distFunction, sh, std::placeholders::_1);
Surface_3 surface(fxn, Sphere_3(ORIGIN,2.));
Run Code Online (Sandbox Code Playgroud)
我得到错误:
~/lib/basisfunctions/SphericalHarmonics2/mesh_an_implicit_function.cpp:62:48:
error: no matching function for call to
‘CGAL::Implicit_surface_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>,
double (*)
(CGAL::Point_3<CGAL::Epick>)>::Implicit_surface_3(std::_Bind<std::_Mem_fn
<double (SphericalHarmonics::*)(CGAL::Point_3<CGAL::Epick>)>
(SphericalHarmonics*, std::_Placeholder<1>)>&, Sphere_3)’
Run Code Online (Sandbox Code Playgroud)
和
~/CGAL-4.1/include/CGAL/Implicit_surface_3.h:50:5: note: no known conversion
for argument 1 from ‘std::_Bind<std::_Mem_fn<double (SphericalHarmonics::*)
(CGAL::Point_3<CGAL::Epick>)>(SphericalHarmonics*, std::_Placeholder<1>)>’ to
‘CGAL::Implicit_surface_3<CGAL::Robust_circumcenter_traits_3<CGAL::Epick>,
double (*)(CGAL::Point_3<CGAL::Epick>)>::Function
{aka double (*)(CGAL::Point_3<CGAL::Epick>)}’
Run Code Online (Sandbox Code Playgroud)
和
~/CGAL-4.1/include/CGAL/Implicit_surface_3.h:34:9: note:
candidate expects 1 argument, 2 provided
Run Code Online (Sandbox Code Playgroud)
[更新]
现在我很清楚我需要一个可以转换为函数指针的函数(即surface需要一个函数指针参数).这排除了std::bind选项.此外,如果它捕获变量(无捕获与捕获lambda),则看起来lambda不能转换为函数指针.所以我认为下面的Andy-Prowl的答案通常是对这个问题的正确答案,尽管我需要找到一个不同的解决办法.
#include <functional>
SphericalHarmonics *sh = new SphericalHarmonics(1);
surface(std::bind(&SphericalHarmonics::distFunction, sh, _1));
Run Code Online (Sandbox Code Playgroud)
选项1:
如果你的成员函数不隐式地处理你的类的实例(因此不需要接收this指针),你可以做到static:
class SphericalHarmonics
{
...
static double distFunction(Point p);
...
};
double SphericalHarmonics::distFunction(Point p)
{
...
}
Run Code Online (Sandbox Code Playgroud)
现在,您的函数将有效地具有单个参数:
surface(SphericalHarmonics::distFunction);
Run Code Online (Sandbox Code Playgroud)
方案2:
否则,可能会使用std::bind()到咖喱成员函数distFunction和固定其第一,隐含参数(如果不使用C++编译器11的工作,可以使用等效的boost::bind()从Boost.Bind库):
#include <functional>
SphericalHarmonics *sh = new SphericalHarmonics(1);
auto fxn = std::bind(&SphericalHarmonics::distFunction, sh, _1);
surface(fxn);
Run Code Online (Sandbox Code Playgroud)
方案3:
或者,在C++ 11中,lambda可以完成这项工作:
SphericalHarmonics *sh = new SphericalHarmonics(1);
auto fxn = [=] (double d) { return sh->distFunction(d); }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
350 次 |
| 最近记录: |