内置类型(int,char等)的析构函数

68
在C++中,以下代码会导致编译器错误:
void destruct1 (int * item)
{
  item->~int();
}

这段代码几乎相同,我只是将int typedef为另一种类型,然后发生了一些神奇的事情:

typedef int myint;

void destruct2 (myint * item)
{
  item->~myint();
}
为什么第二个代码可以工作?一个int因为被typedef了就会获得析构函数吗?
如果你想知道为什么会这样做:这是C++代码重构所需的。我们正在删除标准堆并用自制池替换它。这需要我们调用placement-new和析构函数。我知道对原始类型调用析构函数是无用的,但我们还是希望将它们放在代码中,以防以后用真正的类替换POD。
发现裸的int不行,但typedef的int却可以工作,这真是个惊喜。
顺便说一句,我有一个涉及模板函数的解决方案。我们只需要在模板中使用typedef,一切都会没问题的。

请查看此链接:https://dev59.com/uWAg5IYBdhLWcg3wE3nQ#24000744,也可以检查一下。 - Abhishek Mane
1个回答

109

这就是使你的代码适用于泛型参数的原因。考虑一个容器C:

template<typename T>
struct C {
    // ...
    ~C() {
        for(size_t i = 0; i<elements; i++)
            buffer[i].~T();
    }
};

引入特殊情况来处理内置类型会很麻烦。因此,即使T等于int,C++也允许您执行上述操作。标准文档中在12.4 p15中指出:
“显式调用析构函数的符号可以用于任何标量类型名称。这样做可以编写不需要知道给定类型是否存在析构函数的代码。”
使用普通int和typedef int之间的区别在于它们在语法上是不同的东西。规则是,在析构函数调用之后,~后面的内容是类型名称。int不是这种东西,但typedef名称是。请参考7.1.5.2。

1
我认为这就是 std::is_destructible 在旧编译器(2012-2014)中不一致的原因。 - CoffeDeveloper
这是关于 int 不是类型名称的最后一句话的链接:[dcl.type.simple] - rustyx
@JohannesSchaub-litb item->~myint(); 这行代码到底是做什么的,还是相当于一个空语句 ; - Abhishek Mane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接