![](/img/trans.png)
[英]How to convert void (__thiscall MyClass::* )(void *) to void (__cdecl *)(void *) pointer
[英]How to convert a pointer of type void(*)() to void*
如何将void(*)()
类型的指针转换为void *
?
是否可以使用以下任何一个运算符?
const_cast
static_cast
dynamic_cast
reinterpret_cast
示例:编译以下所有内容( 在Visual Studio 2017中尝试过 ),我想知道它们在转换后是否都具有相同的结果。
void operation(void(*callback)()) {
void* test1 = callback;
void* test2 = static_cast<void*>(callback);
void* test3 = reinterpret_cast<void*>(callback);
}
在ISO标准C ++中,没有从任何函数指针类型到任何对象指针类型的隐式转换。 所以这条线是不正确的。
void* test1 = callback;
对于编译器在没有诊断的情况下接受这个是错误1 (你确实启用了警告,对吗?)
标准C ++中禁止在任何对象指针类型和函数指针类型(任一方向)之间使用static_cast
。 控制规则见5.2.9:
否则,
static_cast
将执行下面列出的转换之一。 不能使用static_cast
明确执行其他转换。
由于上面或下面的规则都没有讨论函数指针强制转换,因此禁止该行
void* test2 = static_cast<void*>(callback);
但是,这不一定是单独的编译器错误,因为其中一个规则允许使用static_cast
来完成任何隐式转换。
最后一行是唯一正确的:
void* test3 = reinterpret_cast<void*>(callback);
reinterpret_cast
规范中提供了控制规则(5.2.10)
有条件地支持将函数指针转换为对象指针类型(反之亦然)。 这种转换的含义是实现定义的,除非实现支持两个方向的转换,将一种类型的prvalue转换为另一种类型并返回,可能具有不同的cv-qualification,将产生原始指针值。
1使用/Za
启用标准兼容模式时,Microsoft C ++编译器会正确拒绝复制初始化和static_cast
尝试:
source_file.cpp(8):错误C2440:'initializing':无法从
void (*)(void)
为void *
source_file.cpp(8):注意:指向的类型是不相关的; 转换需要reinterpret_cast,C风格的转换或函数式转换
source_file.cpp(9):错误C2440:
static_cast
:无法从void (*)(void)
为void *
source_file.cpp(9):注意:指向的类型是不相关的; 转换需要reinterpret_cast,C风格的转换或函数式转换
在标准C ++中,从C ++ 11开始,它是有条件支持的 ,这意味着实现可能支持也可能不支持,并且必须记录它是否受支持。
对于支持此强制转换的实现,要使用的适当强制转换运算符是reinterpret_cast
。 详细信息可以在C ++ 14标准[expr.reinterpret.cast] / 8中找到。
尝试将函数指针转换为没有强制转换([conv.ptr])或static_cast
([expr.static.cast] / 5)的对象指针是错误的。 如果您的编译器在标准模式下允许此操作并且未发出诊断,则编译器不符合要求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.