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