66

在 C++ 中,以下代码给出了编译器错误:

void destruct1 (int * item)
{
  item->~int();
}

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

typedef int myint;

void destruct2 (myint * item)
{
  item->~myint();
}

为什么第二个代码有效?一个 int 是否仅仅因为它已被类型定义而得到一个析构函数?

如果您想知道为什么有人愿意这样做:这来自重构 C++ 代码。我们正在删除标准堆并用自制池替换它。这需要我们调用placement-new 和析构函数。我知道为原始类型调用析构函数是没有用的,但是我们仍然希望在代码中使用它们,以防我们以后用真正的类替换 POD。

发现裸 int 不起作用但 typedefed 起作用是相当令人惊讶的。

顺便说一句 - 我有一个涉及模板功能的解决方案。我们只是在模板中键入定义,一切都很好。

4

1 回答 1

105

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

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

为内置类型引入特殊情况会很烦人。因此 C++ 允许您执行上述操作,即使 T 恰好等于int. 神圣的标准在12.4 p15

显式调用析构函数的符号可用于任何标量类型名称。允许这样做可以编写代码,而不必知道给定类型是否存在析构函数。

使用普通 int 和 typedef'ed int 之间的区别在于它们在语法上是不同的东西。规则是,在析构函数调用中,后面的东西~是类型名。int不是这样的事情,但 typedef-name 是。在 中查找7.1.5.2

于 2009-01-19T02:05:09.290 回答