16

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

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

根据对另一个问题的回答,这个限制“......意味着您不能使用launder获取一个指针,该指针允许您访问比源指针值允许的更多字节,因为未定义行为的痛苦。”

这对于 TC 给出的示例是有意义的,但我不明白在原始对象已被新对象替换的情况下如何解释它,这是预期的原始目的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.寿命]/1.4)。因此,似乎没有可到达的字节,p因为p它不指向任何对象Y。这显然不是预期的阅读内容,因为它会调用std::launder示例中的未定义行为。

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

1 回答 1

1

只是通过示例,相关文本是(粗体是我的):

一个字节的存储空间可以通过一个指向对象 Y 的指针值来访问,如果它在 Y 占用的存储空间内

由于放置 new,指针值现在指向“新放置的”对象,因此可达性就是那个。

我想说这已经足够清楚了。

于 2019-08-30T13:22:09.650 回答