2009-01-19 6 views
53

In C++ den folgenden Code gibt einen Compiler-Fehler:Destructors von eingebauten Typen (int, char etc ..)

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

Dieser Code ist fast das gleiche, ich habe gerade typedef int auf eine andere Art und etwas Magie passiert:

typedef int myint; 

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

Warum funktioniert der zweite Code? Erhält ein int einen Destruktor, nur weil er typedefed ist?

Falls Sie sich fragen, warum Sie das jemals tun möchten: Das kommt vom Refactoring von C++ - Code. Wir entfernen den Standard-Heap und ersetzen ihn durch selbst erstellte Pools. Dazu müssen wir Placement-Neu und die Destruktoren aufrufen. Ich weiß, dass das Aufrufen von Destruktoren für primitive Typen nutzlos ist, aber wir wollen sie trotzdem im Code haben, falls wir später PODs durch echte Klassen ersetzen.

Herauszufinden, dass naked int's nicht funktionieren, aber typedefed tun, war eine ziemliche Überraschung.

Btw - Ich habe eine Lösung, die Template-Funktionen beinhaltet. Wir tippen einfach in die Vorlage und alles ist in Ordnung.

Antwort

77

Dies ist der Grund, warum Ihr Code für generische Parameter funktioniert. Betrachten wir einen Behälter C:

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

Es wäre ärgerlich sein Sonderfälle einzuführen für integrierte Typen. Mit C++ können Sie das oben beschriebene tun, auch wenn T gleich int ist. Der heilige Norm sagt in 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.

Der Unterschied zwischen einem einfachen int verwenden und einen typedef int ist, dass sie syntaktisch verschiedene Dinge sind. Die Regel ist, dass in einem Destruktoraufruf die Sache nach dem ~ ein Typname ist. int ist nicht so eine Sache, aber ein typedef-name ist. Schaut es euch in 7.1.5.2 an.

+13

+1 für "The Holy Standard". – ApprenticeHacker

+0

Ich denke, das ist, was std :: is_destructible in alten Compilern so inkonsistent macht (2012-2014) – GameDeveloper

+0

Kann diese Antwort nicht genug stimmen! – Nils