我认为static_cast<TYPE>()等同于C++中的TYPE(变量)?

I thought static_cast<TYPE>() was equivalent to TYPE(variable) in C++?

本文关键字:TYPE C++ 等同于 中的 变量 lt static gt cast      更新时间:2023-10-16

我刚刚遇到了一些我不太明白的东西。我认为static_cast<TYPE>(variable)TYPE(variable)相当(或更好/更安全)。但是,以下代码不起作用

HMENU hMenu = CreateMenu();
HMENU hSubMenu = CreatePopupMenu();
// File
AppendMenu(hSubMenu, MF_STRING, WndClass_main::ID_FILE_EXIT, "&Quit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, static_cast<intptr_t>(hSubMenu), "&File");

我的编译器说它无法从HMENU转换为intptr_t。顺便说一句,我有一个 64 位系统,它会干扰 void*int 之间的转换?但是,据我了解,类型intptr_t(在 cstdint 中定义)保证足够大,可以容纳void*

有趣的是,以下内容(注意不同的演员表)有效:

HMENU hMenu = CreateMenu();
HMENU hSubMenu = CreatePopupMenu();
// File
AppendMenu(hSubMenu, MF_STRING, WndClass_main::ID_FILE_EXIT, "&Quit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (intptr_t)(hSubMenu), "&File");

我错过了什么?

我认为static_cast<TYPE>(variable)TYPE(variable)相当(或更好/更安全)。

它只是一个子集。有些转换可以由两者执行,但有些转换只能由后者执行。对于函数样式的强制转换,标准在 [expr.type.conv] 中指定:

如果表达式列表是单个表达式,则类型转换表达式等效(在定义性上,如果在含义上定义)与相应的强制转换表达式 (5.4) 等效。

也就是说,TYPE(variable)相当于(TYPE)variable.现在对于后者,标准指定

执行的转换

  • a const_cast(5.2.11),
  • a static_cast(5.2.9),
  • 一个static_cast后跟一个const_cast,
  • a reinterpret_cast (5.2.10),或
  • 一个reinterpret_cast后跟一个const_cast

可以使用显式类型转换的强制转换表示法来执行。

(请注意,还有一个附加文本解释了有关类层次结构的一些差异,这在这里不太相关。
在您的情况下,static_cast是不够的。 reinterpret_cast会,因为它可以将整数转换为指针,反之亦然。因此,首选reinterpret_cast的原因之一是例如,通过搜索潜在危险的铸件来发现的能力。有关何时同时使用两者的进一步查询,请参阅此问题

它更安全。 它也较弱。 它更安全,因为它更弱。

static_cast将执行隐式强制转换,此外,它还会在类层次结构中强制转换指针。

它还将强制投射指向/从具有相同const volatile资格的void*的指针。 (我相信在 C 中是隐含的 - 它不是在C++中)。

这些是 C/C++ 中"更安全"的一组转换。

const_castreinterpret_cast得到更危险的。 其中包括将指针值转换为整数,即使整数足够大。

我的建议是编写这个函数:

intptr_t ptr_to_intptr( void* p ) { return reinterpret_cast<intptr_t>(p); }

这使操作清晰,然后使用它。

(intptr_t)不同,它只适用于指针 - 所以如果你不小心给它喂了一些不是指针的东西。 或者不能存储在intptr_t中的指针,例如指向成员的指针。