在调用其析构函数之前,是否有任何实际理由检查某些东西是否可破坏?
Is there any practical reason to check if something is destructible before calling its destructor?
所以我一直在尝试实现变体/标记的联合类,需要一种方法来编写泛型析构函数,并犯了一个我认为是愚蠢的错误,忘记了某些类型没有析构函数,做类似的事情
template<typename T>
void destruct(T& thing) {
thing.~T();
}
然而,即使对于没有析构函数的类型(如int
或struct A {int b;};
(,这也工作正常。我仍然认为使用这样的东西更具可读性,更容易推理
template<typename T>
void destruct(T& thing) {
if constexpr(std::is_destructible<T>::value) {
thing.~T();
}
}
但是代码之间真的有什么区别吗?第一个对我来说感觉很不确定的行为/只是错误。
然而,即使对于没有析构函数的类型,如 int 或结构 A {int b;},这也工作正常;
这些是微不足道的可破坏类型的示例。调用它们的"析构函数"是很好的定义。它没有任何影响。
但是代码之间真的有什么区别吗?
仅适用于不可破坏的类型。平凡可破坏的类型是可破坏的。
对于不可破坏的类型,如void
、函数类型或具有~T() = delete;
的类型,前一个函数的格式不正确,而后者的格式良好,主体为空。这取决于用例哪个更有用,但默默忽略破坏不可破坏的东西的尝试对我来说似乎是可疑的。
你不需要检查。在此上下文中,对于像int
这样的类型,它转换为伪析构函数调用。结果是几乎无操作
[伪证]
1 在点 . 或箭头 ->运算符后使用伪析构函数名称表示非类类型的析构函数,表示为 类型名称或描述符。结果只能用作 函数调用运算符 (( 的操作数以及此类 调用的类型为 void。唯一的效果是评估 点或箭头之前的后缀表达式。
2 点运算符的左侧应为标量类型。这 箭头运算符的左侧应指向标量 类型。此标量类型是对象类型。简历不合格版本 对象类型和由 伪析构函数名称应为同一类型。此外,两者 表单的伪析构函数名称中的类型名称
嵌套名称说明符opt类型名称 :: ~ 类型名称应指定相同的标量类型(忽略 CV 限定(。
这种表达故意存在于语言中,以便使泛型代码的编写更容易。所以你的destruct
没有if
很好.
顺便说一句,您可能有兴趣知道标准库具有这样的功能。这是std::destroy_at
.除了将数组作为特殊情况处理之外,它几乎可以完成您已经执行的操作。
- 检查输入是否不是整数或数字
- 检查值是否在集合p1和p2中,但不在p3中
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- 如何检查线程是否锁定
- C++LDAP检查用户是否是特定组的成员
- 检查TCHAR数组输入是否为带符号整数C++
- 如何检查QList中是否存在值
- 检查函数返回类型是否与STL容器类型值相同
- 检查是否以特定精度给出双精度
- 检查向量是否具有所有可能的字符组合
- 检查注册表项是否链接到(或副本)另一个注册表项
- 地图计数确实很重要,或者只是检查是否存在
- 检查 2 棵树是否具有相同的顺序
- std::next 是否检查我们是否已经在容器的末尾?
- "!" "== 0"是否检查 int 是否是 0 的好做法?
- 我是否检查是否存在带或不带参数的宏函数
- dynamic_cast是否检查被查询对象的type_info对象,或者递归地检查
- 在VS2010中编译c++ 11中的代码时,std::function()是否检查类型
- 如果第二个参数"0",strcmp 是否C++检查字符串中的每个值?