Деструкторы встроенных типов (int, char и др.).)
в C++ следующий код выдает ошибку компилятора:
void destruct1 (int * item)
{
item->~int();
}
этот код почти такой же, я просто набрал int на другой тип, и что-то волшебное происходит:
typedef int myint;
void destruct2 (myint * item)
{
item->~myint();
}
почему работает второй код? Получает ли int деструктор только потому, что он был typedefed?
в случае, если вы задаетесь вопросом, почему один когда-либо хотел бы сделать это: это происходит от рефакторинга кода C++. Мы удаляем стандартную кучу и заменяем ее самодельными пулами. Этот требует от нас вызова placement-new и деструкторов. Я знаю, что вызов деструкторов для примитивных типов бесполезен, но мы все же хотим, чтобы они были в коде, если мы позже заменим стручки реальными классами.
выяснение того, что голые int не работают, но типизированные делают, было довольно неожиданным.
кстати, у меня есть решение, которое включает в себя шаблон-функции. Мы просто typedef внутри шаблона, и все в порядке.
1 ответ:
это причина, по которой ваш код работает для общих параметров. Рассмотрим контейнер C:
template<typename T> struct C { // ... ~C() { for(size_t i = 0; i<elements; i++) buffer[i].~T(); } };
было бы досадно вводить специальные случаи для встроенных типов. Таким образом, C++ позволяет вам делать выше, даже если T оказывается равным
int
. Святой стандарт говорит в12.4 p15
:нотация для явного вызова деструктора может использоваться для любого имени скалярного типа. Разрешение этого позволяет писать код без необходимости знать, если a деструктор существует для данного типа.
разница между использованием простого int и typedef'Ed int заключается в том, что они синтаксически разные вещи. Правило состоит в том, что в вызове деструктора, вещь после
~
- это имя типа.int
это не такая вещь, но typedef-name есть. Посмотрите его в7.1.5.2
.