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