如何从函数中创建函数指针,并在c++中固定了某些参数
How to create a function pointer from a function with certain parameters fixed in C++
假设我想调用一个函数f,它请求一个类型为
的函数指针int (*foo)(int)
函数类似于
double f( int (*foo)(int))
我有一个这样做的函数,但它接受另一个对象。
int bar(int, MyClass*)
这个对象是在运行时创建的,比如
int main()
// ... read some file / input
MyClass myclass = MyClass(input);
// Now pass the function pointer
double retval = f( bar( int, &myclass))
有没有办法实现最后一行?我正在寻找一个没有全局对象的答案。
No.
你对函数f
有影响吗?在c++中,这将通常是一个可以接受任何可调用对象的模板,或者它将使用一个简单的接口,您可以从中推导。在这两种在这种情况下,您将定义一个可以包含附加数据的类。像这样使用指向函数的指针是非常糟糕的设计。
编辑以说明f
不能被修改的事实:
既然你不能修改f
,我能想到的唯一解决方案是使用某种全局变量和转发函数:
int bar(int i, MyClass * mc);
namespace bar_parameters
{
MyClass * mc = 0;
}
int binded_bar(int i)
{
return bar(i, bar_parameters::mc);
}
int main()
{
MyClass myclass(input);
bar_parameters::mc = &myclass;
double retval = f(binded_bar);
}
这是相当丑陋的,然而…
不能绑定函数的形参。但是,对于functor(函数对象)来说,这是可能的。
您需要做的第一件事是修改f
的参数,使其成为一个函数对象,如std::function
或boost::function
,而不是函数指针:
double f(std::function<int (int)> foo);
这个函数既可以与函数指针一起使用,也可以与具有正确签名的函子一起使用。
在此之后,您可以使用绑定方法,如std/boost::bind
(或c++ 03中的bind1st
/bind2nd
):
double retval = f(std::bind(bar, _1, &myclass));
如果你不能访问Boost或c++ 0x,你可以使用通常的技术,包括制作参数模板,以便接受任何可调用的实体(函数指针和函子):
template <typename Func>
double f(Func foo);
这种方法的缺点是,函数的签名只能通过您在f
中使用它的方式来强制执行。
要绑定第二个参数,然后可以使用ptr_fun
将函数指针转换为函数对象,并使用bind2nd
实际绑定参数:
double retval = f(std::bind2nd(std::ptr_fun(bar), &myclass));
您可以通过使用Boost.Bind实现类似的功能。这现在是c++标准的一部分,甚至可能已经在您的编译器中可用。注意Boost。Bind仍然要求您修改f
的签名。如果这是不可能的,你可以这样做
MyClass* _only_to_be_used_by_ugly;
int ugly(int i) {
return bar(i, _only_to_be_used_by_ugly)
}
int main() {
_only_to_be_used_by_ugly = MyClass(input);
double retval = f(ugly);
}
但我是第一个反对类似方法的人。
在您的情况下,您将不得不做一些邪恶的事情,如:
MyClass* g_myclass = 0;
int my_f(int i) {
return bar(i, g_myclass);
}
int main()
// ... read some file / input
MyClass myclass = MyClass(input);
// Now pass the function pointer
g_myclass = &myclass;
double retval = f(&my_f);
g_myclass = 0; // no longer needed (you hope).
...
}
YMMV。如果你传递的函数指针被保留在某个地方,并在以后再次使用,那么你将陷入麻烦。在这种情况下,您需要有一个静态函数列表和一个指向MyClass的指针全局数组,并根据需要从该列表中分配/释放。可以使用递归模板元程序生成这些函数。不太好,但可能。
或者,找出如何生成所需的汇编程序来执行绑定并在汇编指令中编码MyClass指针。然后在堆上分配该函数。不是很便携,但也应该是可行的。我从来没有尝试过,所以不能保证它会工作或容易做到。代码看起来也很难看。
- 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 函数参数