2009-01-19 50 views
53

在C++下面的代碼給出了一個編譯器錯誤:析構函數內建類型(INT,焦炭等)

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

此代碼幾乎是一樣的,我只是typedef的整型爲另一種類型和一些魔術發生:

typedef int myint; 

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

爲什麼第二個代碼有效? int是否因爲它已被typedefed而獲得析構函數?

如果您想知道爲什麼有人想這樣做:這來自重構C++代碼。我們正在移除標準堆並將其替換爲自制池。這要求我們調用placement-new和析構函數。我知道爲基本類型調用析構函數是沒用的,但是我們希望它們在代碼中,以防我們以後用實際類替換POD。

發現赤裸的int不起作用,但是typedefed的做起來真是令人驚訝。

順便說一句 - 我有一個涉及模板功能的解決方案。我們只需在模板中輸入def並且一切都很好。

回答

77

這就是讓您的代碼適用於通用參數的原因。考慮一個容器C:

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

這將是惱人的內置類型引入特殊情況。因此,即使T恰好等於int,C++也允許您執行上述操作。神聖的標準說,在12.4 p15

The notation for explicit call of a destructor can be used for any scalar type name. Allowing this makes it possible to write code without having to know if a destructor exists for a given type.

使用普通int和Typedef的INT之間的區別是,他們在語法上不同的東西。規則是,在析構函數調用中,~之後的東西是類型名稱。 int是不是這樣的事情,但typedef名稱是。在7.1.5.2中查找它。

+13

+1「The Holy Standard」。 – ApprenticeHacker 2012-01-24 06:03:07