#c #templates
Вопрос:
Попробуйте clang и g , тот же результат для обоих.
fatal error: recursive template instantiation exceeded maximum depth
template<class T>
struct Bar {
~Bar() {
if (ptr) { delete ptr; }
}
Bar<Bar<T>> * ptr{nullptr};
};
int main() { Bar<void> obj; }
Но версия ctor компилируется без ошибок:
template<class T>
struct Bar {
Bar() {
if (ptr) { delete ptr; }
}
Bar<Bar<T>> * ptr{nullptr};
};
int main() { Bar<void> obj; }
В чем проблема с версией dtor?
Комментарии:
1. Это не решает вопроса, но вам не нужно проверять, является ли указатель нулевым, прежде чем удалять его.
delete
правильно обрабатывает нулевые указатели.
Ответ №1:
В чем проблема с версией dtor?
Подумайте о том, что Bar<void> obj;
означает подобное заявление.
Этот объект должен иметь свой деструктор, вызываемый при main
возврате. Таким образом, деструктор ~Bar<void>
будет создан.
Что содержит созданный экземпляр деструктора? delete
Выражение лица. Вы можете возразить, что он проходит проверку на недействительность и поэтому никогда не будет выполнен, но это не имеет значения. Код C разрешен статически и должен быть корректным, даже если компилятор может устранить мертвый код.
Это delete
выражение должно будет вызвать деструктор Bar<Bar<void>>
, и поэтому оно должно быть создано… Промойте и повторите.
С другой стороны, в версии конструктора у вас есть тривиальный деструктор. Он ничего не делает и, конечно, не нуждается в создании экземпляра какого-либо другого типа. Поэтому он отлично компилируется, когда конструктор должен создать его экземпляр.