Aby zrozumieć enum, zacznij od rozważenia destruktora bez niego:
~scoped_ptr() {
delete ptr_;
}
gdzie ptr_jest C*. Jeśli typ Cjest niekompletna w tym momencie, to znaczy, że wszystko jest kompilator wie struct C;, to (1) domyślne generowane zrobić-nic destructor służy do instancji wskazał C. Jest mało prawdopodobne, aby to była właściwa czynność w przypadku obiektu zarządzanego przez inteligentny wskaźnik.
Jeśli usuwanie przez wskaźnik do niekompletnego typu zawsze miało niezdefiniowane zachowanie, to standard może po prostu wymagać, aby kompilator zdiagnozował to i zakończył się niepowodzeniem. Ale jest dobrze zdefiniowane, gdy prawdziwy destruktor jest trywialny: wiedza, którą programista może mieć, ale kompilator nie ma. Dlaczego język definiuje i na to pozwala, jest poza mną, ale C ++ obsługuje wiele praktyk, które dziś nie są uważane za najlepsze praktyki.
Typ kompletny ma znany rozmiar i dlatego sizeof(C)będzie kompilowany wtedy i tylko wtedy, gdy Cjest typem pełnym - ze znanym destruktorem. Więc może być używany jako strażnik. Jeden sposób byłby prosty
(void) sizeof(C);
Ja przypuszczam , że z jakiegoś kompilatora oraz opcje kompilator optymalizuje ją zanim zdążyła zauważyć, że nie należy skompilować i że enumjest sposób, aby uniknąć takiego niezgodnych zachowanie kompilatora:
enum { type_must_be_complete = sizeof(C) };
Alternatywnym wyjaśnieniem wyboru, enuma nie tylko odrzuconego wyrażenia, są po prostu osobiste preferencje.
Lub, jak sugeruje James T. Hugget w komentarzu do tej odpowiedzi: „Wyliczenie może być sposobem na utworzenie pseudo-przenośnego komunikatu o błędzie w czasie kompilacji”.
(1) Domyślnie generowany destruktor nic nie rób dla niekompletnego typu był problemem ze starym std::auto_ptr. Było tak podstępne, że trafiło do artykułu GOTW na temat idiomu PIMPL , napisanego przez przewodniczącego międzynarodowej komisji normalizacyjnej C ++, Herba Suttera. Oczywiście w dzisiejszych czasach to std::auto_ptrjest przestarzałe, zamiast tego użyjemy innego mechanizmu.
ptr_siebie wsizeofassizeof(*ptr_)zamiastsizeof(C).