考虑这样一个野兽:
template<typename Func>
void register_function(Func func) {
// type-erase Func and pass it on to some other function
}
假设可以传递任何可调用的对象。
如果Func
是普通函数类型,我知道如何获得函数的签名。假设func
可以是一个普通函数,一个std::function<F>
,或者一个函数对象(一个std::bind()
表达式),我如何得到函数的参数?
注意:
- 在这种情况下,函数只有0、1或2个参数
- 如果它是一个函数对象,它是
std::bind()
的结果 需要签名来获取参数的类型,这些类型需要在
传递的类型擦除的东西中可用这是严格的 c++ 03(嵌入式平台),所以没有变量模板参数等
不可能。函数对象可以重载或模板化operator()
。因此,它具有"签名"的想法根本不适用,因为它可以具有无限数量的签名。
如果将其限制为只有一个签名,则可以获取operator()的地址,然后使用常规模板特化从成员函数指针类型获取参数。
如果您知道在运行时某个调用的(普通)函数的签名,您可以使用(特别是在Linux上)libffi来调用它。
如果你在运行时甚至不知道要调用的函数的签名,这是不可能的,因为通常ABI约定将根据函数的类型规定传递函数参数的不同方式。
例如,x86-64 ABI(大多数Linux 64位x86-64系统都遵循)要求浮点值和整数值在不同的寄存器中传递。
参见x86调用约定维基页。