当对象在堆栈上而不是堆上时,为什么std::launder
不在Clang和GCC中返回正确的值(2
(?即使使用CCD_ 3。需要std::launder
。参见[ptr.slaugh]/5,上面写着std::launder
在替换在顶级限定的对象const时需要。这是因为[basic.life]/8不允许替换没有std::launder
的完整常量对象,仅限子对象。
#include <memory>
#include <iostream>
int main()
{
struct X { int n; };
const X *p = new const X{1};
const X x{1};
std::construct_at(&x, X{2}); // on stack
const int c = std::launder(&x)->n;
std::construct_at(p, X{2}); // allocated with new
const int bc = std::launder(p)->n;
std::cout << c << " " << 'n';
std::cout << bc << " " << 'n';
}
请参阅编译器资源管理器。
std::construct_at(&x, X{2});
具有未定义的行为。
不允许在以前由具有自动、静态或线程存储持续时间的const
完整对象占用的存储中创建新对象。(参见[基本寿命]/10(
除此之外,您正确地认为第二种情况下需要std::launder
,原因如下:因为您使用new
创建的对象是const
限定的。如果不是这样,旧对象将被新对象透明地替换。