指向具有多个参数作为函数参数的函数的指针
Pointers to functions with multiple arguments as function arguments
我使用优化工具箱中的一个函数来数值计算函数的导数。它接受指向带有一个参数的函数的指针,但如果我需要将指向带有多个参数的功能的指针传递给它,并期望传递其他不太重要的参数,该怎么办?
//Function from toolbox
double num_differentation(double (func(const double)), double x)
{
//makes various calls to func, but with only one parameter
func(x);
}
现在假设我有一个函数,我想传递给上面的函数,但它有额外的参数,与优化问题没有直接关系,但仍然需要这些参数才能为函数得出有意义的结果。
double my_func_to_be_input(double a, double b, double c) {
return a+b*c;
}
有没有办法重写num_differentialion,以便在调用func时通过所有三个参数?我尝试了以下操作,但没有成功:
double num_differentation(double (func(const double arg1, const double arg2, const double arg3)), double x)
{
//makes various calls to func, but with only one parameter
func(x, arg2, arg3);
}
如果我们想更花哨一点,num_differentiation是否有可能接受一个具有不同数量参数的函数,而不相关的参数只是通过?
在任何情况下,我都不想求助于全局变量来路由这些额外的参数。
我使用的是Visual Studio 2013,欢迎任何有用的建议,尤其是具体的代码示例。
更新:这就是我解决问题的方法。
//Rewritten function from toolbox
double rewritten_num_differentation(std::function<double(double)> func, double x)
{
func(x);
}
在我的主代码中:
using namespace std::placeholders;
auto my_func_to_be_input_with_forwarded_arguments= std::bind(my_func_to_be_input, _1, second_argument_to_be_forwarded, third_argument_to_be_forwarded);
return rewritten_num_differentiation(my_func_to_be_input_with_forwarded_arguments, x_arg);
这类似于CrazyEdie提出的第一个解决方案。也许还有一些更优雅的方法不需要重写工具箱函数,但将std::function类型转换为C风格的函数指针似乎非常复杂(就像他们在这里尝试的那样http://www.cplusplus.com/forum/general/63552/)。
double num_differentials(std::function<double(double)> fun, double x)
{
return fun(x);
}
auto n = num_differentials(std::bind(&fun, _1, arg1, arg2), x);
或者:
auto n = num_differentials([arg1,arg2](double x) { return fun(x,arg1,arg2); }, x);
我认为两者都应该在VC2013工作。
编辑以响应更新:
通过C回调系统调用std::function
并不难。
假设:
void register_callback(double (*fun)(double,void*), void* client_data);
写下:
double wrap_legacy(double d, void* client_data)
{
auto fun = static_cast<std::function<double(double)>*>(client_data);
return (*fun)(d);
}
或者,如果你想增加一些安全性,这个:
double wrap_legacy(double d, void* client_data)
{
auto any = static_cast<boost::any*>(client_data);
auto fun = boost::any_cast<std::function<double(double)>>(*any);
return fun(d);
}
在这里,您只需将boost::any
用作任何和所有此类构造的标准类型。始终投射到任意,并始终包裹在任意中。然后,如果有人搞砸了,发送了错误的数据,你会得到异常,而不是未定义的行为。
像这样使用:
auto fun = std::function<double(double)>{[](double d) { return d; }};
register_callback(&wrap_legacy, &fun);
或者安全版本:auto-any=boost::any{std::function{[](double d){return d;}};register_recallback(&wrap_legacy,&fun);
当然,一般来说,client_data生存期要求指向堆分配,所以您需要处理这个问题。你还可以做进一步的包装,比如包装register_callback
,这可以提高安全性。
一个设计良好的C风格工具箱的原型是:
//Function from toolbox
double num_differentation(double (func(const double, void*)),
double x,
void * user_data)
{
//makes various calls to func, but with only one parameter
func(x, user_data);
}
然后期望用户编写
typedef struct my_data { int p; } my_data
double func(double x, void * user_data) {
my_data * data = (my_data*)user_data;
return pow(x, data->p);
}
你可以这样使用图书馆:
my_data data;
data.p = 7;
num_differentiation(&func, 3.0, &data);
然而,这听起来像是你被一个讨厌的工具箱卡住了,"标准"是使用全局,而不是传递用户数据。
my_data g_data;
double func(double x) {
return pow(x, g_data.p);
}
然后像一样使用
g_data.p=7;
num_differentiation(&func, 3.0);
- 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 函数参数