[英]Placement new and assignment of class with const member
为什么这种未定义的行为?
struct s
{
const int id; // <-- const member
s(int id):
id(id)
{}
s& operator =(const s& m) {
return *new(this) s(m); // <-- undefined behavior?
}
};
(从标准引用会很好)。
这个问题来自于这个答案 。
没有什么能够使显示的代码片段本身就是UB。 但是,几乎可以肯定UB会在任何正常使用情况下立即跟进。
来自[basic.life] / 8 (强调我的)
如果在对象的生命周期结束之后并且在重用或释放对象占用的存储之前,则在原始对象占用的存储位置创建新对象,指向原始对象的指针,引用引用原始对象,或者原始对象的名称将自动引用新对象,并且一旦新对象的生命周期开始,就可以用来操纵新对象,如果:
新对象的存储完全覆盖原始对象占用的存储位置,以及
新对象与原始对象的类型相同(忽略顶级cv限定符),和
原始对象的类型不是const限定的,如果是类类型, 则不包含任何类型为const限定的非静态数据成员或引用类型,以及
原始对象是类型为
T
派生程度最高的对象,新对象是类型为T
派生程度最高的对象(也就是说,它们不是基类子对象)。
由于s
有const
成员,因此在调用operator=
之后使用原始变量将是UB。
s var{42};
var = s{420}; // OK
do_something(var.id); // UB! Reuses s through original name
do_something(std::launder(&var)->id); // OK, this is what launder is used for
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.