基本生活/8告诉我们,我们可以在一个对象的生命周期结束后,使用它占用的存储空间来创建一个新的对象,并使用它的原始名称来引用它,除非:
-
原始对象的类型不是 const 限定的,并且,如果是类类型,则不包含任何类型为 const 限定的非静态数据成员或引用类型,并且 [...]
emphasis mine
但是,就在其下方,我们可以看到一条注释:
- 如果不满足这些条件,则可以通过调用从表示其存储地址的指针获得指向新对象的指针
std::launder
这解释了的目的std::launder。我们可以有一个类类型const
成员并使用placement-new在那里创建一个具有不同内部值的新对象。
让我惊讶的是第一句话的第一部分。它清楚地表明,如果存储const
(不一定包含const
成员,但整个对象被声明为const
),我们不能用它来引用一个新对象,但它可能意味着std::launder
可能会修复它。
但我们如何创建这样的对象呢?最简单的例子失败了:
const auto x = 5;
new (&x) auto(10);
这是因为我们无法使用const void*
作为放置新的缓冲区。我们可以const_cast
它,但抛弃了“真实”const
ness 是未定义的行为。我相信这里也是如此。
如果只是禁止使用,我会理解const
对象作为放置新缓冲区,但如果是这种情况,那么第一个引用中强调的部分的目的是什么?我们能否真正使用重用const
不同对象的对象存储?
显然只需要看看just我链接到的标准部分下面有 2 项。基本生活/10告诉我们:
在具有静态、线程或自动存储持续时间的 const 完整对象占用的存储中,或者在此类 const 对象在其生命周期结束之前占用的存储中创建新对象,会导致未定义的行为。
它带有一个示例:
struct B {
B();
~B();
};
const B b;
void h() {
b.~B();
new (const_cast<B*>(&b)) const B; // undefined behavior
}
这最终让我得出一个结论使用是非法的放置-new
一个真正的记忆占据了const
object。因此,我相信问题中提到的注释(参考点8) 是错误的 - 它应该排除有问题的情况。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)