struct X { int n; };
const X *p = new const X{3}; // #1
new (const_cast<X*>(p)) const X{5}; // #2
const int c = std::launder(p)->n;
假设在 处创建的对象#1
是命名obj1
的,而在 处创建的对象#2
是命名的obj2
。的前提std::launder
是
[ptr.launder] p2链接
p 表示内存中一个字节的地址 A。一个在其生命周期内且类型与 T 相似的对象 X 位于地址 A。通过结果可访问的所有存储字节都可通过 p 访问(见下文)。
如果存在对象 Z,则可以通过指向对象 Y 的指针值访问存储 b 的字节,与 Y 可互转换的指针,这样 b 位于 Z 占用的存储空间内,或者如果 Z 位于立即封闭的数组对象内是一个数组元素。
这个规则有点晦涩。以下解释是否正确?
obj2
将占用以 .sizeof(X)
开头的字节数A
。将Y
(指向的对象std::launder(p)
) 和Z
(即obj2
) 视为同一个对象,它们是指针可互转换的,并且它们所sizeof(X)
占用的字节obj2
都在 内Z
,因此这些字节都可以通过 到达std::launder(p)
。也就是说,“可以通过结果访问的所有存储字节”。这些字节是否可以通过p
?假设Y
(即p
指向的对象) 和Z
是同一个对象obj1
,它们也是假设数组的数组元素,根据 [basic.compound] p3
不是数组元素的 T 类型对象被认为属于具有一个 T 类型元素的数组。
由于这些以开头的字节A
都在数组中,其中数组Z
是一个元素。因此,我们可以说这些字节都可以通过p
?