调用一个平凡的析构函数有什么影响?

What is the effect of call to a trivial destructor?

对普通析构函数的调用会结束对象的生命周期吗? 我读了 this and this 但没有找到很好的解释。这些线程声明一个简单的析构函数调用没有效果,像 struct A { int x; } a; a.~A(); a.~A(); 这样的代码是合法的。 但是我在标准中找到了那个例子:

struct C { };
void f() {
    C * pc = new C;
    using C2 = C;
    pc->C::~C2(); // OK, destroys *pc
    C().C::~C(); // undefined behavior: temporary of type C destroyed twice
    using T = int;
    0 .T::~T(); // OK, no effect
    0.T::~T(); // error: 0.T is a user-defined-floating-point-literal (5.13.8)
}

此处 C 具有平凡的析构函数,但 C 类型对象的双重析构仍具有未定义的行为?

从 C++20 开始,琐碎的析构函数调用结束了对象的生命周期。在此之前他们没有,多次调用析构函数是有效的。

在 C++17(草案 N4659)中,平凡的析构函数被明确排除在 [basic.life]/1.3 and objects with trivial destructor would live instead until their storage duration ends or their storage is reused ([basic.life]/1.4 的生命周期结束之外。

这已根据 CWG issue 2256 in this draft commit 的决议进行了更改。

另请注意,伪析构函数调用 也会结束 C++20 中的生命周期,但在此之前不会。您 link 中的两个问题都在谈论此类伪析构函数调用。请参阅草案 (N4861) 的 [diff.cpp17.basic]/1 中针对 C++17 的兼容性说明。