C++ 标准的哪一部分禁止双重销毁?

问题描述 投票:0回答:1

现代 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中的措辞似乎有更改为也禁止微不足道的析构函数这样做。对于琐碎的析构函数来说,这似乎应该没问题,所以我怀疑我错过了一些东西。

c++ language-lawyer c++20 c++23
1个回答
0
投票

[basic.life]/6.2

...对象的生命周期结束后...程序具有未定义的行为,如果:

—指针用于...调用对象的非静态成员函数

现在析构函数是非静态成员函数吗?是的,

[class.mem.special]/1

...或者,如果这是一个 伪析构函数调用 (即,如果

T
是非类),那么出于不同的原因它是 UB。
[expr.call]/4
表示它结束了对象的生命周期,如果没有对象(因为它的生命周期已经结束),则前提条件为 false,因此行为未定义。

是否有任何条件允许这样做,例如如果 T 有一个简单的析构函数?

好像不是这样的。

© www.soinside.com 2019 - 2024. All rights reserved.