Le fait d'être un type POD est-il exactement équivalent à un type trivial à disposition standard?

22

En C ++ 20, le concept de POD est déconseillé, soi-disant parce que c'est un trait composite insignifiant d'être trivial et de mise en page standard. Cependant, la définition du POD dans le projet C ++ 20 n'est pas exactement "à la fois triviale et standard"; c'est en fait:

Une classe POD est une classe qui est à la fois une classe triviale et une classe de mise en page standard, et n'a pas de membres de données non statiques de type classe non-POD (ou tableau de celle-ci). Un type POD est un type scalaire, une classe POD, un tableau d'un tel type ou une version qualifiée cv de l'un de ces types.

En d'autres termes, non seulement un type POD est à la fois trivial et standard, mais il l'est également de manière récursive.

Cette exigence récursive est-elle redondante? En d'autres termes, si un type est à la fois trivial et standard, est-il automatiquement récursif trivial et standard également? Si la réponse est "non", alors quel est un exemple d'un type banal de mise en page standard qui n'est pas POD?

Brian
la source

Réponses:

12

En C ++ 20, le concept de POD est déconseillé, soi-disant parce que c'est un trait composite insignifiant d'être trivial et de mise en page standard.

Incorrect. Le terme POD est déconseillé car il n'a plus d'importance :

Le terme POD ne sert plus à un objectif dans la norme, il est simplement défini et des restrictions s'appliquent lorsque quelques autres types préservent cette propriété résiduelle.

Essentiellement, un type qui est à la fois trivial et à disposition standard ne gagne aucune capacité au-delà de ce qui est à lui seul trivial et à disposition standard. La combinaison des deux ne rend pas le type spécial et les deux propriétés n'ont pas vraiment grand-chose à voir l'une avec l'autre.

La disposition standard consiste à bien définir la disposition de ses sous-objets non vides (ainsi que ses sous-objets de classe de base vides ne perturbant pas la disposition du type). La trivialité consiste à savoir si l'objet a une signification au-delà du bloc de bits qu'il stocke (et s'il s'agit d'un objet conceptuellement valide s'il est initialisé avec un bloc de bits arbitraire).

Si je crée un modèle qui prend un type Tet que je veux voir si je peux des memcpyobjets de ce type, je me fiche de la disposition de ses membres; Je veux savoir si c'est TriviallyCopyable. De même, l'exactitude de offsetofne se soucie pas du tout si la classe a un constructeur de copie fourni par l'utilisateur. Tout ce qui compte, c'est si la disposition des sous-objets membres se produit dans un ordre clair et imposé.

Fondamentalement, les gens ont regardé autour de eux et ont réalisé qu'il ne restait rien en C ++ qui ait spécifiquement besoin de l' intersection de la trivialité et de la mise en page standard. Nous n'avons donc pas besoin de lui réserver un terme. Les quelques endroits où la norme stipule expressément qu'un certain type sera "POD" peuvent simplement être remplacés par "disposition triviale et standard", selon le cas.

Cette exigence récursive est-elle redondante?

Étant donné que les deux exigences constitutives sont individuellement récursives, l'intersection des deux est également récursive. Il n'est donc pas explicitement nécessaire de déclarer que tous les sous-objets sont également POD. C'était plus que probablement un cas d'une bizarrerie de copier-coller, où la définition d'origine disait quelque chose comme "tous les membres de données non statiques doivent être de type POD" et ils ont juste gardé cette déclaration telle quelle.

Nicol Bolas
la source
" Tout ce qui lui importe, c'est que la disposition des sous-objets membres se fasse dans un ordre clair et imposé par les normes " Pourquoi le std devrait-il appliquer une ordonnance pour pouvoir déterminer le décalage d'un membre? Est-ce un objectif de la std de permettre des implémentations folles là où les membres n'ont pas de compensation?
curiousguy
1

La disposition standard dépend de la disposition standard des membres non statiques:

[class.prop]

Une classe S est une classe à présentation standard si:

  • n'a pas de membres de données non statiques de type classe de disposition non standard (ou tableau de ces types) ou référence,

  • ...

La trivialité dépend également de la trivialité des membres non statiques. Par souci de concision, je n'ai cité que la règle du constructeur par défaut, mais les autres fonctions membres spéciales ont un libellé similaire:

[class.default.ctor]

Un constructeur par défaut est trivial s'il n'est pas fourni par l'utilisateur et si:

  • ...
  • pour tous les membres de données non statiques de sa classe qui sont de type classe (ou tableau de ceux-ci), chacune de ces classes a un destructeur trivial.

Pour autant que je sache, l'exigence explicite de PODness à appliquer aux membres est redondante, car elle découle également implicitement des exigences de mise en page standard et triviale.

eerorika
la source