如何将双参数函数"cast"为单参数函数?
How to "cast" a two-argument function into a one-argument function?
在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捕获变量(无捕获vs.捕获lambda),则它似乎不能转换为函数指针。所以我认为Andy-Prowl下面的答案通常是这个问题的正确答案,尽管我需要找到一个不同的解决方案。
选项1:
如果您的成员函数不隐式地工作在类的实例上(因此不需要接收this
指针),您可以将其设置为static
:
class SphericalHarmonics
{
...
static double distFunction(Point p);
...
};
double SphericalHarmonics::distFunction(Point p)
{
...
}
现在,您的函数将有效地拥有一个参数:
surface(SphericalHarmonics::distFunction);
选项2:
否则,您可以使用std::bind()
来curry成员函数distFunction
并修复其第一个隐式参数(如果您不使用c++ 11编译器,您可以使用Boost中的等效boost::bind()
)。绑定库):
#include <functional>
SphericalHarmonics *sh = new SphericalHarmonics(1);
auto fxn = std::bind(&SphericalHarmonics::distFunction, sh, _1);
surface(fxn);
选项3:
或者,在c++ 11中,lambda可以完成这项工作:
SphericalHarmonics *sh = new SphericalHarmonics(1);
auto fxn = [=] (double d) { return sh->distFunction(d); }
使用std::bind或boost::bind:
#include <functional>
SphericalHarmonics *sh = new SphericalHarmonics(1);
surface(std::bind(&SphericalHarmonics::distFunction, sh, _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的等值面类只能处理函数指针(与std::function
等相反)。但问题只是我们用的方式定义了它。只要定义Surface_3
使用std::function<FT (Point_3)>
作为模板参数,Andy Prowl的答案中的std::bind
和lambdas就可以正常工作:
...
typedef std::function<FT (Point_3)> Function;
typedef CGAL::Implicit_surface_3<GT, Function> Surface_3;
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 当从函数参数中的临时值调用复制构造函数时
- 如何从"decltype()"获取函数参数的数量<funtion>?
- 如何将lambda作为模板类的成员函数参数
- 模板参数推导失败,函数参数/参数不匹配
- 如何在C++中将迭代器作为函数参数传递
- 将函数参数"const char*"转换为"std::string_view"是
- C++ 如何将数组值解压缩为函数参数
- 主函数参数的属性
- 具有两个间接寻址运算符 (C++) 的函数参数的用途
- "Warning: Comma within array index expression"但逗号分隔函数参数
- 如何定义在用作函数参数时工作的类模板的转换
- 将函数参数完美转发到函数指针:按值传递呢?
- 为什么我不能将引用作为 std::async 的函数参数传递
- 什么..(省略号)作为函数原型中唯一的函数参数,C++?
- 是否可以就地构造一个固定大小的数组作为函数参数?
- 接受模板作为函数参数
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- Arduino 函数参数