我刚刚遇到了一些我不太了解的事情。我认为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");
我错过了什么?
答案 0 :(得分:5)
我认为
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),- a
static_cast
后跟const_cast,- a
reinterpret_cast
(5.2.10)或- a
reinterpret_cast
后跟const_cast
,可以使用显式类型转换的强制转换表示法执行。
(请注意,还有一个附加文本解释了有关类层次结构的一些差异,这在这里并不十分相关。)
在您的情况下,static_cast
是不够的。 reinterpret_cast
会,因为它可以将整数转换为指针,反之亦然。 reinterpret_cast
应该优先考虑的原因之一是通过搜索潜在危险的演员阵容找到的能力。有关何时使用两者的进一步查询,请参阅this question。
答案 1 :(得分:2)
更安全。它也较弱。它更安全,因为它更弱。
static_cast
将执行隐式转换,此外它会将指针向下转换为类层次结构。
它还会使用相同的void*
const
条件投射指向/ volatile
的指针。 (我认为隐含在C中 - 它不在C ++中)。
这些是C / C ++中“更安全”的演员阵容。
const_cast
和reinterpret_cast
获得更危险的内容。这些包括将指针值转换为整数,即使整数足够大。
我的建议是写下这个功能:
intptr_t ptr_to_intptr( void* p ) { return reinterpret_cast<intptr_t>(p); }
使操作变得清晰,然后使用它。
与(intptr_t)
不同,它只适用于指针 - 所以如果你不小心给它一些不是指针的东西。或者指针不能存储在intptr_t
中,如指向成员的指针。