C++ 在调用其析构函数之前,是否有任何实际的理由来检查某个东西是否是可破坏的?

C++ 在调用其析构函数之前,是否有任何实际的理由来检查某个东西是否是可破坏的?,c++,C++,所以我一直在尝试实现一个变体/标记的联合类,需要一种编写泛型析构函数的方法,犯了一个我认为是愚蠢的错误,忘记了某些类型没有析构函数 template<typename T> void destruct(T& thing) { thing.~T(); } 但是,代码之间实际上有什么区别吗?第一个对我来说是相当不明确的行为 然而,即使对于没有析构函数的类型,如int或struct A{int b;},这种方法也可以很好地工作 这些都是可破坏性很小的类型的例子。调用它们

所以我一直在尝试实现一个变体/标记的联合类,需要一种编写泛型析构函数的方法,犯了一个我认为是愚蠢的错误,忘记了某些类型没有析构函数

template<typename T> 
void destruct(T& thing) {
    thing.~T();
}
但是,代码之间实际上有什么区别吗?第一个对我来说是相当不明确的行为

然而,即使对于没有析构函数的类型,如int或struct A{int b;},这种方法也可以很好地工作

这些都是可破坏性很小的类型的例子。调用它们的“析构函数”定义很好。它没有效果

但是,代码之间实际上有什么区别吗

仅适用于不可破坏的类型。平凡的可破坏类型是可破坏的


对于不可破坏类型,例如
void
、函数类型或具有
~T()=delete的类型,第一个函数的格式不正确,而后一个函数的格式良好,主体为空。这取决于哪个用例更有用,但在我看来,默默地忽略破坏不可破坏的东西的尝试似乎是可疑的。

您不需要检查。在这个上下文中,对于像
int
这样的类型,它转换为伪析构函数调用。结果几乎没有任何效果

1在点后使用伪析构函数名称。或箭头-> 运算符表示由表示的非类类型的析构函数 类型名称或decltype说明符。该结果仅可作为参考 函数调用运算符()的操作数,以及 调用的类型为void。唯一的影响是对 点或箭头前的后缀表达式

2点运算符的左侧应为标量类型。这个 箭头运算符的左侧应为指向标量的指针 类型。此标量类型是对象类型。简历不合格的版本 对象类型和 伪析构函数名称应为相同类型。此外,两个 在表单的伪析构函数名称中键入名称

nested-name-specifieropttype-name :: ~ type-name 嵌套名称说明符OPTTYPE名称:: ~ 类型名 应指定相同的标量类型(忽略cv鉴定)

为了使泛型代码的编写更容易,这种表达式故意存在于语言中。因此,如果没有
if
,您的
析构函数就可以了


另外,您可能有兴趣知道标准库有这样一个函数。是的。除了作为特例处理数组之外,它几乎与您已经做过的一样。

如果有些东西不可描述,您通常不想首先构造一个。一个类型是可构造的而不是可破坏的,这是非常奇怪的。编辑:显式调用析构函数甚至更奇怪。唯一的用例是匹配新的放置。这是用于某种分配器的吗?为什么要按值接收对象来销毁它?如果您按值接收它,那么当函数返回时,它将被销毁,而您没有执行任何操作(但它可能被构造为首先调用函数)始终是合法的,即使
T
int
。就我个人而言,我不会写if语句,@NathanOliver如果析构函数是
=delete
private
,则是不合法的。if感觉应该是一个
静态断言
。对不可破坏类型调用
destruct
可能没有意义。私有或已删除的析构函数呢?@NathanOliver-它们呢?(A) OP询问了一些根本没有析构函数的类型。(B) 标准库本身认为这种病理学在实践中不值得费心。你找不到一个标准的容器来处理这样的类型。 nested-name-specifieropttype-name :: ~ type-name