考虑一下这个 union :

union A{
  int a;
  struct{
    int b;
    } c;
  };
ca不是layout-compatibles类型,因此无法通过b读取a的值:
A x;
x.c.b=10;
x.a+x.a; //undefined behaviour (UB)
对于审判1和审判2,请参见this question
试用3
现在,让我们使用std::launder来实现它似乎不想要的功能:
A x;
x.a=10;
auto p = &x.a;                 //(1)
x.c.b=12;                      //(2)
p = std::launder(p);           //(2')
*p+*p;                         //(3)  UB?
std::launder可以更改任何内容吗?根据[ptr.launder]:

粗体的句子强调了困扰我的东西。如果p是无效的指针值,那么如何访问任何存储字节?另一方面,读取std::launder只是不可用。
否则,可以将(2)处的p的值作为一个指针值,该值代表[basic.life] 的“注释”中所提到的存储区域:

最佳答案

注释中明确允许使用
无需basic.life std::launder contains the following rule:

这种“新对象是在原始对象所占的存储位置创建的”案例在此明确适用,因为:

满足所有项目符号条件,因为"potentially overlapping subobject"引用基类子对象,而 union 成员则不。 (在您链接的版本中,该项目符号直接提到了基类子对象。)
但是,即使这种解释要针对 union 而改变,该注释也特别提到std::launder绕过了此限制。
请注意,较早版本的Standard将该子对象排除在此规则之外...但是该注释清楚地表明std::launder也将绕过该问题。

10-02 20:23