如何将 void(*)() 类型的指针转换为 void*

How to convert a pointer of type void(*)() to void*

本文关键字:void 指针 转换 类型      更新时间:2023-10-16

如何将类型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 限定(应生成原始指针值。


1当使用/Za启用符合标准的模式时,Microsoft C++编译器会正确拒绝复制初始化并static_cast尝试:

source_file.cpp(8(: 错误 C2440:"正在初始化": 无法从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( 是错误的。 如果编译器在标准模式下允许此操作,并且未发出诊断,则编译器不符合要求。