当 std::is_trivial_v 为真时,T 可以有一个析构函数<T>吗?


#include <type_traits>
struct A
{
~A() {}
};
int main()
{
static_assert(std::is_trivial_v<A>); // error   
}

如果A具有析构函数,那么std::is_trivial_v<A>将是false

但是,从std::is_trivial的cppref页面来看,没有什么要求A必须不具有析构函数。

std::is_trivial_v<T>为真时,T是否可以具有析构函数

你需要深入兔子洞。cpprreference页面指出,琐碎类型需要TriviallyCopyable。如果你访问该页面,它需要

琐碎的未删除析构函数

如果我们访问该链接,我们将获得

琐碎的析构函数

如果以下各项都为真,则类T的析构函数是微不足道的:

  • 析构函数不是用户提供的(也就是说,它要么隐式声明,要么在第一次声明时显式定义为默认值(
  • 析构函数不是虚拟的(也就是说,基类析构函数是非虚拟的(
  • 所有直接基类都有琐碎的析构函数
  • 类类型(或类类型的数组(的所有非静态数据成员都具有平凡的析构函数

平凡的析构函数是一个不执行任何操作的析构构函数。具有琐碎析构函数的对象不需要delete表达式,可以通过简单地释放其存储来处理。所有与C语言兼容的数据类型(POD类型(都是可破坏的。

所以,是的,它需要一个琐碎的析构函数,而用户提供的空析构函数并不被认为是琐碎的。

你唯一能";写";一个析构函数,并且被认为是微不足道的,就是使用

~ClassName() = default;

std::is_trivial_v<T>为true时,T是否可以具有析构函数?

它不能有一个非平凡的析构函数。如果以下所有情况都为真,则类T的析构函数是微不足道的:

  • 析构函数不是用户提供的(也就是说,它要么隐式声明,要么显式定义为第一个析构函数的默认值声明(
  • 析构函数不是虚拟的(也就是说,基类析构函数是非虚拟的(
  • 所有直接基类都有琐碎的析构函数
  • 类类型(或类类型的数组(的所有非静态数据成员都具有平凡的析构函数

当一个类型是平凡的时,意味着它意味着它可以被平凡地销毁
像您那样明确定义方法将不符合此约束
但你可以做的是:

struct A {
~A() = default;
};
static_assert(std::is_trivial<A>::value);

最新更新