Подтвердить что ты не робот

Деструкторы встроенных типов (int, char и т.д.)

В С++ следующий код дает ошибку компилятора:

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

Этот код почти тот же, я просто набираю int на другой тип и происходит что-то волшебное:

typedef int myint;

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

Почему работает второй код? Разве int получает деструктор только потому, что он был набран?

В случае, если вам интересно, почему это когда-либо хотелось бы сделать это: это происходит из рефакторинга кода на С++. Мы удаляем стандартную кучу и заменяем ее самодельными пулами. Это требует от нас вызова - нового и деструкторов. Я знаю, что вызов деструкторов для примитивных типов бесполезен, но мы хотим, чтобы они были в коде, если мы позже заменим POD на реальные классы.

Выяснив, что голый int не работает, но набираемые команды были неожиданностью.

Btw - У меня есть решение, которое включает в себя шаблонные функции. Мы просто печатаем внутри шаблона, и все в порядке.

4b9b3361

Ответ 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.