如何解释std::launder的可达性要求?

How to interpret the reachability requirement of std::launder?

本文关键字:launder 可达性 std 何解释 解释      更新时间:2023-10-16

std::launder函数要求通过结果可以访问的每个字节都可以通过参数访问。"可访问"的定义如下:

存储

字节可以通过指向对象Y的指针值访问,如果该对象位于Y占用的存储内,则该对象是 指针可与 Y 互转换,如果Y是数组元素,则立即封闭的数组对象。

根据对另一个问题的回答,这种限制"......意味着您不能使用launder来获取允许您访问比源指针值允许的更多的字节的指针,这会导致未定义的行为。

这对于 T.C. 给出的示例是有意义的,但我不明白在原始对象被新对象替换的情况下如何解释它,这是std::launder考虑的原始目的。该标准具有以下示例:

struct X { const int n; };
X *p = new X{3};
const int a = p->n;
new (p) X{5}; // p does not point to new object (6.8) because X::n is const
const int b = p->n; // undefined behavior
const int c = std::launder(p)->n; // OK

在这种情况下,当调用std::launder时,p---原始X对象---指向的对象已经不复存在,因为在它占用的存储中创建一个新对象已经隐式地结束了它的生存期([basic.life]/1.4(。因此,似乎没有字节可以通过p访问,因为p不指向任何对象Y。这显然不是预期的读数,因为它会调用示例中std::launder未定义的行为。

  1. 我是否误解了这里的措辞,还是措辞有缺陷?
  2. 使
  3. 示例有效的预期含义是什么?

仅凭示例,相关文本是(粗体是我的(:

可以通过指向的指针值访问存储字节 对象 Y(如果它位于 Y 占用的存储内(

由于放置了 new,指针值现在指向"新放置"的对象,因此可访问性是这样的。

我想说,就目前而言,这一点已经足够清楚了。