伪析构函数调用不会破坏对象

11 c++ destructor primitive-types language-lawyer explicit-destructor-call

请考虑以下代码:

#include <iostream>

typedef int t;
t a=42;

int main()
{
    a.t::~t();
    std::cout << a; //42
}
Run Code Online (Sandbox Code Playgroud)

我预计a会被摧毁.但事实并非如此,为什么?伪析构函数调用将如何销毁该对象?

Col*_*mbo 26

但事实并非如此,为什么?

§5.2.4/ 1:

唯一的效果是在点或箭头之前评估后缀表达式.

其中postfix-expression是发生调用的对象的表达式.因此,伪析构函数调用作为对普通析构函数的调用,不会终止它所应用的对象的生命周期.例如,

int i = 0;
(i += 5).~decltype(i)();
std::cout << i;
Run Code Online (Sandbox Code Playgroud)

你实际上不能为标量调用析构函数,因为它们没有标量(见[class.dtor]).该语句仅允许用于模板代码,在该模板代码中,您可以调用您不知道类型的对象的析构函数 - 它消除了为标量类型编写特殊化的必要性.


注释中注意到[expr.pseudo]确实暗示了scalars的析构函数的存在

在点或箭头运算符后使用伪析构函数名称表示由type-name命名的非类型类型的析构函数..->

但是,这与标准的其他部分不一致,例如§12,它将析构函数称为特殊成员函数,并提到

析构函数用于销毁其类类型的对象.

它似乎是在C++ 98天创建的不精确.

  • +1这是正确的答案.它将通过扩展的标准引用来改进(您引用的部分不足以完全理解该行为). (2认同)
  • @Matt 访问 a 很好,因为 a 的生命周期没有按照 3.8 的规定结束。措辞可能很草率,是的。一旦我回来并拥有一台笔记本电脑,我可能会扩展答案。 (2认同)
  • @PravasiMeet没有"伪析构函数"这样的东西,伪析构函数调用根本不调用 - 调用是伪的,而不是析构函数.一个简单的析构函数只是一个根本不执行任何操作的析构函数(即无操作). (2认同)