void f(string str,int i )
{
cout<<str.c_str()<<endl;
cout<<i<<endl;
}
typedef void (*PF)(int i,string str);
int _tmain(int argc, _TCHAR* argv[])
{
PF pf=(PF)(void*)&f;
pf(10,string()); //runtime-error
return 0;
}由于某些需要,我需要使用数据类型已被擦除的f的地址调用函数f (如上面的代码)。但是这种解决方案可能会导致不安全的函数调用,因为在编译过程中不能检查数据类型。当参数的类型与参数的类型不同时,有没有办法让编译器报告一个错误?
如下所示:
void f(T1 i,T2 j)
{
T1 p* = new i.real_type; //if i.real_type is different from T1, it will lead a compiling
....
}我非常感谢这一点。
发布于 2012-07-21 02:43:06
C++中唯一可用的运行时类型信息是typeid和dynamic_cast,它们只适用于多态类型(具有虚函数的类类型)。函数指针不存储必要的信息。
实际上,你应该避免将函数指针转换为。唯一需要函数指针大小写的地方是在GetProcAddress或dlsym的返回值上。
发布于 2012-07-21 02:49:54
不是的。没有安全的方法可以从void*中“获取类型”。可能有一种干净的方法来解决你的实际问题,这样就不需要void*了。我建议你在那里发布一个新的问题,解释你的具体任务。
发布于 2012-07-21 03:02:07
有一些方法可以让编译器在参数类型与参数类型不同时报告错误。
它怎么会知道呢?您颠覆了类型系统(这就是强制转换为void*所做的)。您告诉C++编译器假装函数指针是指向任何东西的指针,然后告诉它假装这个指向任何东西的指针是指向不同类型函数的指针。
编译器无法知道原始类型是什么。它所知道的就是有一个void*,而你要求将它转换成某个东西。为了让void*能够工作,C++语言不需要编译器神奇地知道void*来自哪里以及它曾经是什么。因此,您可以将其强制转换为任何类型,但规范规定,如果您将其强制转换为非原始类型,则会得到未定义的行为。
C++中的类型系统允许编译器检测您何时做错了什么。通过颠覆它,然后做错了,你已经放弃了生活在一个理性宇宙中的所有权利。你告诉编译器,“我知道我在做什么”,然后开枪打自己的脚。
你能做的最好的事情就是使用Boost.Any来存储你的函数指针。任何将其强制转换为除最初存储在其中的内容之外的任何内容的尝试都将抛出异常。当然,是在运行时。
https://stackoverflow.com/questions/11584886
复制相似问题