现代 C++ 标准(C++20 或 C++23 都可以)的哪些部分规定是否可以重用对象的存储而不使用放置 new 运行其析构函数?
alignas(T) std::byte storage[sizeof(T)];
T* p = new (storage) T(...);
p = new (storage) T(...)
p->~T();
如果一般情况下不允许,是否有任何条件允许,例如如果
T
有一个简单的析构函数?
C++20 标准在 [basic.life]/9 中明确指出,可以在不调用析构函数的情况下重用存储:
对于类类型的对象,在重用或释放该对象占用的存储空间之前,程序不需要显式调用析构函数;但是,如果没有显式调用析构函数,或者没有使用删除表达式来释放存储,则不会隐式调用析构函数,并且任何依赖于析构函数产生的副作用的程序都具有未定义的行为。
对于具有简单析构函数的类型,这似乎完全无害:根据定义,它们的析构函数没有副作用,因此程序不能依赖它们。
对于任意类型,这似乎不是一个特别好的主意,但我找不到任何语言表明它是 UB 独立于程序其余部分的功能。