2009-01-19 4 views
53

En C++ le code suivant donne une erreur de compilation:Destructeurs de types builtin (int, char, etc ..)

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

Ce code est à peu près le même, je viens typedef l'int à un autre type et quelque chose de magique arrive:

typedef int myint; 

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

Pourquoi le deuxième code fonctionne-t-il? Est-ce qu'un int obtient un destructeur juste parce qu'il a été typedefed?

Dans le cas où vous vous demandez pourquoi on aimerait faire ceci: Cela vient du refactoring du code C++. Nous supprimons le tas standard et le remplaçons par des piscines auto-fabriquées. Cela nous oblige à appeler placement-nouveau et les destructeurs. Je sais que l'appel de destructeurs pour les types primitifs est inutile, mais nous voulons qu'ils soient dans le code au cas où nous remplacerions plus tard les POD par de vraies classes. Découvrir que les ints nus ne fonctionnent pas mais que les typedefed sont assez surprenants. Btw - J'ai une solution qui implique des fonctions de gabarit. Nous juste typedef à l'intérieur du modèle et tout va bien.

Répondre

77

C'est la raison pour laquelle votre code fonctionne pour les paramètres génériques. Considérons un conteneur C:

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

Il serait ennuyeux d'introduire des cas spéciaux pour les types intégrés. Donc, C++ vous permet de faire ce qui précède, même si T arrive à int. La sainte norme dit dans 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.

La différence entre l'utilisation d'un int simple et un typedef int est que ce sont des choses syntaxiquement différentes. La règle est que, dans un appel de destructeur, la chose après le ~ est un nom de type. int n'est pas une telle chose, mais un typedef-name est. Recherchez-le dans 7.1.5.2.

+13

+1 pour "The Holy Standard". – ApprenticeHacker

+0

Je pense que c'est ce qui rend std :: is_destructible si incohérent au sein des anciens compilateurs (2012-2014) – GameDeveloper

+0

Ne peut pas assez voter pour cette réponse! – Nils

Questions connexes