2009-01-19 14 views
53

W C++ następujący kod daje błąd kompilatora:destruktory z wbudowanych typów (int, char itp ..)

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

Ten kod jest prawie taka sama, ja po prostu typedef int do innego typu i coś magicznego dzieje się:

typedef int myint; 

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

Dlaczego działa drugi kod? Czy int dostaje destruktora tylko dlatego, że został typeded?

Jeśli zastanawiasz się, dlaczego ktoś chciałby to zrobić: pochodzi z refaktoryzacji kodu C++. Usuwamy standardowe sterty i zastępujemy je własnymi zbiorami. To wymaga od nas wywoływania nowych miejsc docelowych i destruktorów. Wiem, że wywoływanie destruktorów dla typów pierwotnych jest bezużyteczne, ale chcemy je w kodzie mimo to na wypadek, gdybyśmy później zastąpili POD z prawdziwymi klasami.

Dowiedzenie się, że nagie inty nie działają, ale typowe, to była niespodzianka.

Btw - Mam rozwiązanie, które obejmuje funkcje szablonu. W szablonie wpisaliśmy tylko typef i wszystko jest w porządku.

Odpowiedz

77

Jest to powód, dla którego twój kod działa dla ogólnych parametrów. Rozważ pojemnik C:

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

Byłoby denerwujące wprowadzenie specjalnych przypadków dla typów wbudowanych. Tak więc C++ pozwala na wykonanie powyższych czynności, nawet jeśli T ma wartość równą int. Standardowe święty mówi 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.

Różnica między używaniem zwykły int i int typedef'ed jest to, że są one składniowo różne rzeczy. Zasadą jest, że w wywołaniu destruktora rzeczą po nazwie ~ jest nazwa typu. int nie jest taką rzeczą, ale jest to nazwa typefaktu. Sprawdź to w 7.1.5.2.

+13

+1 dla "Świętego Standardu". – ApprenticeHacker

+0

Myślę, że to właśnie sprawia, że ​​std :: is_destructible jest tak niekonsekwentny w starych kompilatorach (2012-2014) – GameDeveloper

+0

Nie mogę odpowiedzieć na tę odpowiedź wystarczająco! – Nils