You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

类能否无析构函数?该模板代码中各编译器谁符合C++标准?

类是否可以不具备析构函数?C++标准与编译器行为分析

问题背景

是否存在C++类可以不具备析构函数(即不可销毁)?以下示例代码引发了不同编译器的分歧:

#include <type_traits>

template <typename T>
struct A {
  ~A() requires(std::is_void_v<T>);
  //~A() requires(!std::is_void_v<T>) = default;
};

template struct A<int>;

编译器行为差异

  • GCC 13.2:编译通过,认为A<int>存在有效析构函数
  • Clang 17.0:报错:error: no viable destructor found for class 'A<int>'
  • MSVC 19.38:报错:error C7653: 'A<int>': failed to select a destructor for the class

添加被注释的代码行(~A() requires(!std::is_void_v<T>) = default;)后,所有编译器均可正常编译。

正确行为与标准依据

Clang和MSVC的行为符合C++标准,GCC存在不符合标准的实现。

根据C++标准[class.dtor]章节的规定:

  1. 若类中显式声明了任意析构函数(包括带约束的析构函数),编译器不会隐式生成默认析构函数。
  2. 对于模板特化A<int>,声明的析构函数~A() requires(std::is_void_v<T>)因约束std::is_void_v<int>为false而不可用。此时由于已有显式声明的析构函数,编译器不会自动补充生成默认析构函数,导致A<int>没有可用的析构函数,程序属于格式错误。

当添加带反向约束的默认析构函数后,A<int>特化会匹配到~A() requires(!std::is_void_v<T>) = default;,该析构函数约束满足且为默认生成的有效析构函数,因此解决了无可用析构函数的问题。

GCC的错误在于,它在已有显式声明析构函数(即使该析构函数因约束不可用)的情况下,仍然隐式生成了默认析构函数,这违反了标准中“显式声明析构函数则禁止隐式生成”的规则。

内容的提问来源于stack exchange,提问作者Cassio Neri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:56:08