2009-01-19 14 views
53

En C++ el siguiente código da un error del compilador:destructores de tipos internos (int, char, etc ..)

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

Este código es casi el mismo, sólo typedef int a otro tipo y algo mágico sucede:

typedef int myint; 

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

¿Por qué funciona el segundo código? ¿Un int obtiene un destructor solo porque ha sido typedefed?

En caso de que se pregunte por qué alguna vez le gustaría hacer esto: Esto proviene de la refactorización del código C++. Estamos eliminando el montón estándar y reemplazándolo con grupos propios. Esto requiere que llamemos colocación nueva y los destructores. Sé que llamar a los destructores para tipos primitivos es inútil, pero queremos que estén en el código, sin embargo, en caso de que más adelante sustituyamos los POD por clases reales.

Descubrir que las int desnudas no funcionan, pero las de tipo type do es bastante sorprendente.

Btw - Tengo una solución que implica plantillas de funciones. Simplemente tipeamos dentro de la plantilla y todo está bien.

Respuesta

77

Es la razón por la que su código funciona para parámetros genéricos. Considere un contenedor C:

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

Sería molesto introducir casos especiales para los tipos incorporados. Entonces C++ le permite hacer lo anterior, incluso si T pasa a ser igual a int. La santa estándar dice en 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 diferencia entre usar un int normal y una int typedef'ed es que son sintácticamente diferentes cosas. La regla es que en una llamada de destructor, la cosa que sigue al ~ es un nombre de tipo. int no es una cosa así, pero es un typedef-name. Búscalo en 7.1.5.2.

+13

+1 for "The Holy Standard". – ApprenticeHacker

+0

Creo que esto es lo que hace que std :: is_destructible sea tan inconsistente dentro de los viejos compiladores (2012-2014) – GameDeveloper

+0

¡No se puede votar esta respuesta lo suficiente! – Nils