2017-07-16 97 views
2

如何将void(*)()类型的指针转​​换为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); 
} 
+0

当你尝试过时发生了什么? –

+1

您的问题是否存在根本原因? –

+1

可移植的,你不能。 – Quentin

回答

4

在ISO标准C++中,没有从任何函数指针类型到任何对象指针类型的隐式转换。所以这条线是不合格的。

void* test1 = callback; 

对于编译器接受这种没有诊断是错误(你有启用了警告,对不对?)

static_cast任何对象指针类型和函数指针类型之间(任一方向)在标准C++中是被禁止的。控制规则见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,应该产生原始指针值。


当使用/Za启用标准兼容模式时,Microsoft C++编译器不正确地拒绝复制初始化和static_cast尝试:

source_file.cpp(8):错误C2440:'初始化':无法从void (*)(void)转换为void *

source_file.cpp(8):note:Types of types是无关的;转换要求reinterpret_cast,C样式转换 或函数样式转换

source_file.cpp(9):错误C2440:static_cast: 不能从void (*)(void)转换为void *

source_file.cpp(9): 笔记:指向的类型是不相关的;转换需要 reinterpret_cast,C风格演员表或演员风格演员表

3

在标准C++,由于C++ 11,它是有条件地支持,这意味着实现可能或可能不支持它,而且必须记录它是否被支持。

对于确实支持这种转换的实现,要使用的相应投射运算符为reinterpret_cast。细节可以在C++ 14标准[expr.reinterpret.cast]/8中找到。

尝试将函数指针转换为没有强制转换的对象指针([conv.ptr])或static_cast([expr.static.cast]/5)时出错。如果你的编译器在标准模式下允许这样做,并且不发出诊断,那么编译器是不合格的。

+1

'const_cast'也可以被应用,但是这个例子不适合那个。 – user0042

+1

@ user0042'const_cast'只能用于添加或删除cv-qualifiers –

+0

当然!我提到这个例子并不合适。 – user0042

相关问题