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

Does the effect of std::launder last after the expression in which it is called?

考虑以下示例代码:

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?
    }
}

函数fun会根据语言标准打印什么?换句话说,std::launder 的效果是否持续超出调用它的表达式?或者,每次我们需要访问 u.x.n?

的更新值时,我们都必须使用 std::launder

cppereference 非常明确:

std::launder has no effect on its argument. Its return value must be used to access the object. Thus, it's always an error to discard the return value.

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