Pow*_*ice 58 c++ language-lawyer
struct A
{
~A() = delete;
};
int main()
{
new A{};
}
Run Code Online (Sandbox Code Playgroud)
这无法编译,并显示错误消息:
错误:使用已删除的函数'A :: ~A()'new A {};
据我所知,我没有破坏对象,为什么它试图调用析构函数?
用GCC 8.1.0编译
g++ -std=c++17 -O2
Run Code Online (Sandbox Code Playgroud)
Bar*_*rry 37
让我们自下而上.
除了声明它之外,隐式或显式引用已删除函数的程序是不正确的.
显然,我们没有~A()明确指出.我们是否隐含地提到它?[class.dtor]/12:
隐式调用析构函数
- 对于在程序终止时具有静态存储持续时间([basic.stc.static])的构造对象([basic.start.term]),
- 对于在线程出口处具有线程存储持续时间([basic.stc.thread])的构造对象,
- 对于具有自动存储持续时间([basic.stc.auto])的构造对象,当创建对象的块退出时([stmt.dcl]),
- 对于构造的临时对象,它的生命周期结束([conv.rval],[class.temporary]).
或者在[expr.new]/20中:
如果new-expression创建了类类型的对象数组,则可能会调用析构函数.
我们有这些东西吗?不,这里没有自动,静态或线程存储持续时间的对象,也没有构造的临时对象,我们的new-expression也没有创建数组.这里只有一个对象,一个A具有动态存储持续时间的对象,我们正在进行聚合初始化.
既然我们既没有明确也没有暗示~A(),我们就不能绊倒这条规则.因此,gcc bug.另请注意,gcc接受new A;和new A();,就此规则而言具有相同的含义.