Деструкторы встроенных типов (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 55

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.