为什么在Clang和GCC中,当对象在堆栈上而不是堆上时,std::launder
不返回正确的值(2
)?即使使用std::launder
。需要std::launder
。请参阅[ptr.launder]/5,其中说明在替换顶级限定的对象常量时需要std::launder
。这是因为[basic.life]/8不允许替换没有std::launder
的完整const对象,只允许替换子对象。
#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';
}
1条答案
按热度按时间7vux5j2d1#
std::construct_at(&x, X{2});
有未定义的行为。不允许在先前由
const
完整对象占用的存储中创建新对象,该对象具有自动、静态或线程存储持续时间。(见[basic.life]/10)除此之外,你是正确的,因为你解释的原因,在第二种情况下需要
std::launder
:因为用new
创建的对象是const
限定的。如果不是这样的话,旧的对象将被新的对象“透明地替换”。