现代 C++ 标准(C++20 或 C++23 都可以)的哪些部分规定不能使用放置 new 和显式析构函数调用来两次销毁对象?
alignas(T) std::byte storage[sizeof(T)];
T* const p = new (storage) T(...);
p->~T();
p->~T();
是否有任何条件允许这样做,例如如果
T
有一个简单的析构函数?
我发现这个之前的答案是一个半相关的问题,它给出了问题的琐碎析构函数部分的相对清晰的答案,但它使用C ++ 17,令我惊讶的是C ++ 20中的措辞似乎有更改为也禁止微不足道的析构函数这样做。对于琐碎的析构函数来说,这似乎应该没问题,所以我怀疑我错过了一些东西。
[basic.life]/6.2
...对象的生命周期结束后...程序具有未定义的行为,如果:
—指针用于...调用对象的非静态成员函数
[class.mem.special]/1
。
...或者,如果这是一个 伪析构函数调用 (即,如果
T
是非类),那么出于不同的原因它是 UB。 [expr.call]/4
表示它结束了对象的生命周期,如果没有对象(因为它的生命周期已经结束),则前提条件为 false,因此行为未定义。
是否有任何条件允许这样做,例如如果 T 有一个简单的析构函数?
好像不是这样的。