std::launder 的效果是否在调用它的表达式之后持续?

Joh*_* Li 5 c++ compiler-optimization language-lawyer stdlaunder

考虑以下示例代码:

struct X { const int n; };
union U { X x; float f; };
void fun() {
  U u = {{ 1 }};
  u.f = 5.f;               // OK, creates new subobject of 'u'
  X *p = new (&u.x) X {2}; // OK, creates new subobject of 'u'
  
  if(*std::launder(&u.x.n) == 2){// condition is true because of std::launder
    std::cout << u.x.n << std::endl;  //UB here?
    }
}
Run Code Online (Sandbox Code Playgroud)

函数会fun根据语言标准打印什么?换句话说,std::launderlast 的效果是否超出了它被调用的表达式?std::launder或者,我们每次需要访问更新后的值时都必须使用u.x.n?

ala*_*ner 5

cppereference对此非常明确:

std::launder 对其参数没有影响。必须使用它的返回值来访问该对象。因此,丢弃返回值总是错误的。

至于标准本身,它没有任何地方声明它的参数也被洗白(或没有),但函数的签名表明在我看来:指针是按值而不是引用获取的,因此不能在调用者可见的任何方式。