template<class T> inline void checked_delete(T * x) { // intentionally complex - simplification causes regressions typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; (void) sizeof(type_must_be_complete); delete x; }
Для чего нужны такие сложности и почему упрощение приведет к регрессу? Дело вот в чем: чтобы корректно удалить объект, его тип должен быть полностью определен (complete type). Проверяется это в несколько этапов:
- Вызов оператора sizeof для неопределенного типа приведет к ошибке компиляции.
- На случай, если sizeof вернет 0 (в случает нестандартного расширения в компиляторе), создается массив с отрицательной длинной, что запрещено во всех компиляторах.
- Вторая строка нужна для компилятора Metrowerks CodeWarrior, который не будет инстанцировать первый typedef, пока он не используется.
- Преобразование результата sizeof к void нужно, чтобы избежать предупреждений во время компиляции.
Ссылки: