简短的答案:
如果您不知道reinterpret_cast
代表什么,请不要使用它。如果将来需要它,您将知道。
完整答案:
让我们考虑基本数字类型。
例如int(12)
,当您转换为unsigned float (12.0f)
处理器时,由于两个数字的位表示形式不同,因此需要调用一些计算。这就是static_cast
代表。
另一方面,在调用时reinterpret_cast
,CPU不会调用任何计算。它只是像对待其他类型一样对待内存中的一组位。所以,当你转换int*
到float*
与此关键字,新的值(指针dereferecing之后)无关,在数学意义上的旧值。
示例:的确,reinterpret_cast
由于一种原因-字节顺序(字节序),所以不可移植。但这常常是令人惊讶的使用它的最佳理由。让我们想象一下这个例子:您必须从文件中读取二进制的32位数字,并且您知道它是大尾数法。您的代码必须是通用的,并且可以在大字节序(例如某些ARM)和小字节序(例如x86)系统上正常工作。因此,您必须检查字节顺序。这在编译时是众所周知的,因此您可以编写constexpr
函数:您可以编写函数来实现此目的:
/*constexpr*/ bool is_little_endian() {
std::uint16_t x=0x0001;
auto p = reinterpret_cast<std::uint8_t*>(&x);
return *p != 0;
}
说明:x
内存中的二进制表示形式可能是0000'0000'0000'0001
(big)或0000'0001'0000'0000
(little endian)。重新解释广播后,p
指针下的字节可以分别为0000'0000
或0000'0001
。如果您使用静态广播,则0000'0001
无论使用哪种字节序,它始终为。
编辑:
在第一个版本中,我将示例函数is_little_endian
设为constexpr
。它可以在最新的gcc(8.3.0)上编译良好,但标准说这是非法的。clang编译器拒绝对其进行编译(正确)。
reinterpret_cast
在运行时不会发生。它们都是编译时语句。来自en.cppreference.com/w/cpp/language/reinterpret_cast:“与static_cast不同,但与const_cast一样,reinterpret_cast表达式不会编译为任何CPU指令。它纯粹是一个编译器指令,它指示编译器对待位序列。 (对象表示形式),就像它具有类型new_type一样。”