Pour comprendre le enum
pour commencer à considérer le destructeur sans elle :
~scoped_ptr() {
delete ptr_;
}
où ptr_
es un C*
. Si le type C
est incomplet à ce stade, c'est-à-dire que tout ce que le compilateur sait est struct C;
entonces (1) a généré par défaut le destructeur do-nothing est utilisé pour l'instance C pointée. Il est peu probable que ce soit la bonne chose à faire pour un objet géré par un pointeur intelligent.
Si la suppression via un pointeur vers un type incomplet avait toujours eu un comportement indéfini, alors la norme pourrait simplement exiger que le compilateur le diagnostique et échoue. Mais c'est bien défini quand le vrai destructeur est trivial : une connaissance que le programmeur peut avoir, mais que le compilateur n'a pas. Je ne sais pas pourquoi le langage définit et permet cela, mais le C++ supporte de nombreuses pratiques qui ne sont pas considérées aujourd'hui comme des bonnes pratiques.
Un type complet a une taille connue, et donc, sizeof(C)
compilera si et seulement si C
est un type complet -- avec un destructeur connu. Il peut donc être utilisé comme garde. Une façon de faire serait de simplement
(void) sizeof(C); // Type must be complete
Je voudrais devinez qu'avec un certain compilateur et certaines options, le compilateur l'optimise avant même qu'il puisse remarquer qu'il ne devrait pas compiler, et que le enum
est un moyen d'éviter un tel comportement non conforme du compilateur :
enum { type_must_be_complete = sizeof(C) };
Une explication alternative pour le choix de enum
plutôt qu'une simple expression abandonnée, est simplement une préférence personnelle.
Ou comme le suggère James T. Hugget dans un commentaire à cette réponse, "L'enum peut être un moyen de créer un message d'erreur pseudo-portable au moment de la compilation".
(1) Le destructeur do-nothing généré par défaut pour un type incomplet posait un problème avec les anciennes versions de l'outil. std::auto_ptr
. C'était si insidieux qu'il a fait son chemin dans un article de GOTW sur l'idiome PIMPL écrit par le président du comité international de normalisation du C++, Herb Sutter. Bien sûr, de nos jours std::auto_ptr
est déprécié, on utilisera plutôt un autre mécanisme.