在matlab中,可以写:
S = @(x,y) x^2+y^2-1
G = @(x) S(x,1);
如果我有一个期望单参数函数的函数,我可以做到以上几点。我怎样才能在c / c ++中做到这一点?
我有一个库函数(来自CGAL库),它希望作为一个参数,一个函数本身只有一个参数。理想情况下,我有一个类(SphericalHarmonics
),我希望有一个成员函数,它接受一个参数。所以我有:
FT SphericalHarmonics::distFunction(Point_3 p)
(请注意,FT
类似于double
)但当然我尝试时
SphericalHarmonics *sh = new SphericalHarmonics(1);
Surface_3 surface(sh->distFunction, Sphere(ORIGIN,2.));
this
也被视为参数,我的distFunction
函数是双参数函数,并抛出错误。
请注意,这可以通过全局变量来解决,即
SphericalHarmonics *sh;
FT dist_function(Point_3 p) {
return sh->distFunction(p);
}
main() {
sh = new SphericalHarmonics(1);
Surface_3 surface(dist_function);
}
但是,这真的不理想。我想要一种没有全局变量的方法,因为能够拥有一个可以轻松地与CGAL库集成的类函数会好得多。
提前致谢!
[增订]
@ Andy-Prowl:我已尝试过您的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.));
我收到了错误:
~/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)’
和
~/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>)}’
和
~/CGAL-4.1/include/CGAL/Implicit_surface_3.h:34:9: note:
candidate expects 1 argument, 2 provided
[增订]
现在我很清楚我需要一个可以转换为函数指针的函数(即surface
需要一个函数指针参数)。这排除了std::bind
选项。而且,如果lambda捕获变量(capture-less vs. capturing lambdas),它似乎无法转换为函数指针。所以我认为下面的Andy-Prowl的回答通常是对这个问题的正确答案,尽管我需要找到一个不同的解决办法。
答案 0 :(得分:5)
#include <functional>
SphericalHarmonics *sh = new SphericalHarmonics(1);
surface(std::bind(&SphericalHarmonics::distFunction, sh, _1));
答案 1 :(得分:5)
选项1:
如果您的成员函数不是隐式地处理您的类的实例(因此不需要接收this
指针),您可以使它成为static
:
class SphericalHarmonics
{
...
static double distFunction(Point p);
...
};
double SphericalHarmonics::distFunction(Point p)
{
...
}
现在,你的函数实际上只有一个参数:
surface(SphericalHarmonics::distFunction);
选项2:
否则,您可以使用std::bind()
来修改成员函数distFunction
并修复其第一个隐式参数(如果您不使用C ++ 11编译器,则可以使用等效的{来自Boost.Bind库的{1}}:
boost::bind()
选项3:
或者,在C ++ 11中,lambda可以完成这项工作:
#include <functional>
SphericalHarmonics *sh = new SphericalHarmonics(1);
auto fxn = std::bind(&SphericalHarmonics::distFunction, sh, _1);
surface(fxn);
答案 2 :(得分:1)
在处理CGAL的模板化Surface_3
类的特定情况下。你可能正在使用这样的东西(来自他们的例子)来定义Surface_3
类型:
typedef CGAL::Surface_mesh_default_triangulation_3 Tr;
// c2t3
typedef CGAL::Complex_2_in_triangulation_3<Tr> C2t3;
typedef Tr::Geom_traits GT;
typedef GT::Sphere_3 Sphere_3;
typedef GT::Point_3 Point_3;
typedef GT::FT FT;
typedef FT (*Function)(Point_3);
typedef CGAL::Implicit_surface_3<GT, Function> Surface_3;
这是误导性的,因为它看起来像CGAL的isosurface类只能处理函数指针(而不是std::function
等)。但问题只在于我们只是以那种方式定义。只需定义Surface_3
以使用std::function<FT (Point_3)>
作为模板参数,std::bind
和Andy Prowl's answer中的lambdas就可以正常运行:
...
typedef std::function<FT (Point_3)> Function;
typedef CGAL::Implicit_surface_3<GT, Function> Surface_3;