提问人:sbi 提问时间:8/19/2014 最后编辑:David Gsbi 更新时间:8/19/2014 访问量:543
如何从任何可调用的函数中获取有意义的函数签名
How to get a meaningful function signature from anything callable
问:
想想这样的野兽:
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()
注意:
- 在这种情况下,函数只有零个、一个或两个参数
- 如果它是一个函数对象,它是
std::bind()
为了获取参数的类型,需要签名,这些类型需要在传递的类型擦除的东西中使用
这是严格的 C++03(嵌入式平台),因此没有变量模板参数等。
答:
10赞
Puppy
8/19/2014
#1
不可能的。函数对象可以重载或模板化。因此,它具有“签名”的想法根本不适用,因为它可以具有无限数量的签名。operator()
如果将其限制为只有一个签名,则可以获取 operator() 的地址,然后使用常规模板专用化从成员函数指针类型获取参数。
评论
0赞
sbi
8/19/2014
好吧,我没有想到过载的函子.不过,它在这里并不适用。如果它是一个函子,它是 的结果,并且只有一个重载。operator()
std::bind()
1赞
Puppy
8/19/2014
std::bind
生成模板化 S。operator()
0赞
sbi
8/19/2014
是的,我不知道如何推断这些,也不知道如何区分所有可能性,以便使用正确的机制来破解签名。
0赞
Basile Starynkevitch
8/19/2014
#2
如果你在运行时知道某个被调用的(普通)函数的签名,你可以使用(特别是在 Linux 上)libffi 来调用它。
如果你在运行时甚至不知道要调用的函数的签名,那是不可能的,因为一般来说,ABI 约定会根据函数参数的类型来规定传递函数参数的不同方式。
例如,x86-64 ABI(在大多数 Linux 64 位 x86-64 系统上遵循)要求在不同的寄存器集中传递浮点值和整数值。
例如,请参阅 x86 调用约定 wikipage。
评论
1赞
sbi
8/19/2014
我提到了类型擦除。为此,我需要编译时的类型。方便的是,我也在编译时提供了它们,因为它们嵌入在 的签名中。我只需要破解它.在编译时。F
F
评论
std::function
对象。