- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
根据 ISO C++ 委员会的最后一次 session ,bit-cast将在 C++20 标准中引入。
我知道 reinterpret_cast
不适合这份工作,因为 type aliasing rules但我的问题是,为什么他们选择不扩展 reinterpret_cast
以将对象视为位序列表示,而更愿意将此功能作为一种新的语言结构提供?
最佳答案
嗯,有一个明显的原因:因为它不会做 bit_cast
所做的所有事情。即使在我们可以在编译时分配内存的 C++20 世界中,reinterpret_cast
也被禁止在 constexpr
函数中使用。 bit_cast
的明确目标之一是能够在编译时做这些事情:
Furthermore, it is currently impossible to implement a
constexpr
bit-cast function, asmemcpy
itself isn’tconstexpr
. Marking the proposed function asconstexpr
doesn’t require or preventmemcpy
from becomingconstexpr
, but requires compiler support. This leaves implementations free to use their own internal solution (e.g. LLVM has abitcast
opcode).
现在,您可以说您可以将 reinterpret_cast
的这种特定用法扩展到 constexpr
上下文。但这使规则变得复杂。与其简单地知道 reinterpret_cast
不能在 constexpr
代码段中使用,还不如记住 reinterpret_cast
不能使用的具体形式使用。
此外,还有一些实际问题。即使你想走 reinterpret_cast
路线,std::bit_cast
也是一个库函数。通过委员会获得库功能总是比语言功能更容易,即使它会获得一些编译器支持。
然后是更主观的东西。 reinterpret_cast
通常被认为是一种固有的危险操作,表明以某种方式“欺骗”了类型系统。相比之下,bit_cast
不是。它正在生成一个新对象,就像从现有对象中复制其值表示一样。它是一个低级工具,但它不是一个与类型系统混淆的工具。因此,将“安全”操作的拼写方式与“危险”操作的拼写方式相同会很奇怪。
确实,如果您确实以相同的方式拼写它们,就会开始质疑为什么这是合理定义的:
float f = 20.4f;
int i = reinterpret_cast<int>(f);
但这有点糟糕:
float f = 20.4f;
int &i = reinterpret_cast<int &>(f);
当然,语言律师或熟悉严格别名规则的人会理解为什么后者不好。但是对于外行来说,如果可以使用 reinterpret_cast
进行位转换,则不清楚为什么使用 reinterpret_cast
来转换指针/引用和将现有对象解释为转换后的类型。
不同的工具应该有不同的拼写。
关于C++20 bit_cast 与 reinterpret_cast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53401654/
我最近了解到 C++ 标准包含“严格的别名规则”,它禁止通过不同类型的变量引用相同的内存位置。 但是,该标准确实允许 char 类型合法地别名任何其他类型。这是否意味着 reinterpret_cas
我需要将一段代码从 C++ 转换为 VB6。 具体来说,这个: reinterpret_cast(reinterpret_cast(lParam)->hwndParent) 有人能告诉我这在 VB6
我正在编写与对齐相关的代码,如果给定的指针正确对齐,却没有标准的功能测试,这让我感到非常惊讶。 似乎互联网上的大多数代码都使用(long)ptr或 reinterpret_cast(ptr)测试对齐,
这个问题在这里已经有了答案: Why is reinterpret_cast not constexpr? (2 个答案) 关闭去年。 我遇到了以下错误: class NormalClass { p
我recently learned通过 reinterpret_casting 其地址将 POD 重新解释为不同的 POD 是未定义行为。所以我只是想知道 reinterpret_cast 的潜在用例
考虑以下程序: struct A{}; int main() { A a; A b = a; A c = reinterpret_cast(a); } 编译器 (g++14)
我recently learned通过 reinterpret_casting 其地址将 POD 重新解释为不同的 POD 是未定义行为。所以我只是想知道 reinterpret_cast 的潜在用例
它为什么会存在?在什么情况下它不会导致严格的别名违规,在哪些情况下会导致? 我的意思是,如果你在两个不兼容的类型之间进行转换,并且该转换的结果是唯一指向它在整个程序中使用的内存的指针,那么在假设没有其
这两个cast语句是一样的吗?它们产生相同的结果。 const std::int16_t i = 3; char a[ 2 ]; *reinterpret_cast(a) = i; reinterp
我已经编写了 MyString 和 MyStringConst 类。现在我需要不时地将 MyString 作为 MyStringConst 传递,因此重载强制转换运算符。这是我写的 MyString:
我有一个结构 S,它将两个类型为 T 的固定大小的数组打包在一起。 template struct S { array, 10> x1; array x2; }; 我想获取对大小为 2
如果我已将结构的成员复制到我的类中,我是否可以从我的类转换为结构? #include #include class Buffer { public: void * address;
#include struct A { int a; }; struct I1 : A { int a; }; struct I2 : A { int a; }; struct D : I1, I2
是否可以使用 reinterpret_cast 将 const 限定符仅添加到结构的一个成员。 #include std::pair test; std::pair& ctest = reinter
int main() { class_name object; object.method(); fstream file("writeobject.dat" , ios::o
当我注意到它的输出完全错误时,我正在测试一个简单的编译器。事实上,输出的字节顺序从小变大了。经过仔细检查,违规代码原来是这样的: const char *bp = reinterpret_cast(&
基本思想是创建一个可变大小的数组,在构造时固定,并在单个分配单元中创建另一个类,以减少开销并提高效率。分配缓冲区以适应数组,并使用另一个对象和新放置来构造它们。为了访问数组的元素和另一个对象,使用了指
#include struct I1 { virtual void nb1()=0; virtual ~I1(){} }; struct I2 { virtual void n
我刚刚在使用reinterpret_cast的代码中发现了一个错误,将其更改为dynamic_cast后,问题就消失了。然后,我尝试使用以下代码重现该行为: 1 #include 2 3
我想知道有没有一种不用大量复制就可以解决这个问题的好方法。 例如,假设我有一个字节缓冲区,我在其中保存了很多东西。我会正确地在其中保存 4 个字节的整数和 float 等。 现在,如果我的整数保存在缓
我是一名优秀的程序员,十分优秀!