Ist ein POD-Typ genau gleichbedeutend mit einem trivialen Standard-Layout-Typ?

22

In C ++ 20 ist das Konzept von POD veraltet, angeblich weil es ein bedeutungsloses zusammengesetztes Merkmal von Trivialität und Standardlayout ist. Die Definition von POD im C ++ 20-Entwurf ist jedoch nicht genau "sowohl trivial als auch Standardlayout". es ist eigentlich:

Eine POD-Klasse ist eine Klasse, die sowohl eine Trivialklasse als auch eine Standardlayoutklasse ist und keine nicht statischen Datenelemente vom Typ Nicht-POD-Klasse (oder Array davon) enthält. Ein POD-Typ ist ein Skalartyp, eine POD-Klasse, ein Array eines solchen Typs oder eine lebenslaufqualifizierte Version eines dieser Typen.

Mit anderen Worten, ein POD-Typ ist nicht nur trivial und standardisiert, sondern auch rekursiv.

Ist diese rekursive Anforderung überflüssig? Mit anderen Worten, wenn ein Typ sowohl trivial als auch Standardlayout ist, ist er dann automatisch auch rekursiv trivial und Standardlayout? Wenn die Antwort "Nein" lautet, was ist dann ein Beispiel für einen trivialen Standardlayout-Typ, der kein POD ist?

Brian
quelle

Antworten:

12

In C ++ 20 ist das Konzept von POD veraltet, angeblich weil es ein bedeutungsloses zusammengesetztes Merkmal von Trivialität und Standardlayout ist.

Falsch. Der Begriff POD wird abgelehnt, weil er keine Rolle mehr spielt :

Der Begriff POD erfüllt im Standard keinen Zweck mehr, er ist lediglich definiert, und Einschränkungen gelten, wenn einige andere Typen diese Resteigenschaft bewahren.

Im Wesentlichen gewinnt ein Typ, der sowohl trivial als auch Standardlayout ist, keine Fähigkeiten, die über das hinausgehen, was Trivialität und Standardlayout für sich allein bieten. Die Kombination der beiden macht den Typ nicht besonders, und die beiden Eigenschaften haben nicht wirklich viel miteinander zu tun.

Beim Standardlayout geht es darum, dass das Layout der nicht leeren Unterobjekte genau definiert ist (sowie der leeren Basisklasse-Unterobjekte, die das Layout des Typs nicht stören). Bei Trivialität geht es darum, ob das Objekt über den von ihm gespeicherten Bitblock hinaus eine Bedeutung hat (und ob es konzeptionell ein gültiges Objekt ist, wenn es mit einem beliebigen Bitblock initialisiert wird).

Wenn ich eine Vorlage erstelle, die einen Typ annimmt T, und ich sehen möchte, ob ich memcpyObjekte dieses Typs kann, ist mir das Layout der Mitglieder egal. Ich möchte wissen, ob es TriviallyCopyable ist. Ebenso ist offsetofes nicht im geringsten wichtig, ob die Klasse über einen vom Benutzer bereitgestellten Kopierkonstruktor verfügt. Es geht nur darum, ob das Layout der Mitgliedsunterobjekte in einer klaren, vom Standard erzwungenen Reihenfolge erfolgt.

Grundsätzlich haben sich die Leute umgesehen und festgestellt, dass in C ++ nichts mehr übrig ist, was speziell die Schnittstelle zwischen Trivialität und Standardlayout benötigt. Wir müssen also keine Laufzeit dafür reservieren. Die wenigen Stellen, an denen der Standard ausdrücklich angibt, dass ein Typ "POD" sein wird, können gegebenenfalls einfach durch "Trivial- und Standardlayout" ersetzt werden.

Ist diese rekursive Anforderung überflüssig?

Da beide Bestandteile einzeln rekursiv sind, ist auch der Schnittpunkt der beiden rekursiv. Es muss also nicht ausdrücklich angegeben werden, dass alle Unterobjekte auch POD sind. Dies war mehr als wahrscheinlich nur ein Fall von Seltsamkeit beim Kopieren und Einfügen, bei dem in der ursprünglichen Definition so etwas wie "Alle nicht statischen Datenelemente müssen POD-Typen sein" stand und diese Aussage unverändert beibehalten wurde.

Nicol Bolas
quelle
" Es geht nur darum, ob das Layout der Mitgliedsunterobjekte in einer klaren, durch Standard erzwungenen Reihenfolge erfolgt. " Warum müsste der Standard eine Reihenfolge erzwingen, um den Versatz eines Mitglieds bestimmen zu können? Ist es ein Ziel des Standards, verrückte Geräte zuzulassen, bei denen Mitglieder keinen Offset haben?
Neugieriger
1

Das Standardlayout hängt vom Standardlayout nicht statischer Elemente ab:

[class.prop]

Eine Klasse S ist eine Standardlayoutklasse, wenn:

  • hat keine nicht statischen Datenelemente vom Typ Nicht-Standard-Layout-Klasse (oder Array solcher Typen) oder Referenz,

  • ...

Trivialität hängt auch von der Trivialität nicht statischer Mitglieder ab. Der Kürze halber habe ich nur die Regel für den Standardkonstruktor angegeben, aber die anderen speziellen Elementfunktionen haben einen ähnlichen Wortlaut:

[class.default.ctor]

Ein Standardkonstruktor ist trivial, wenn er nicht vom Benutzer bereitgestellt wird und wenn:

  • ...
  • Für alle nicht statischen Datenelemente ihrer Klasse, die vom Klassentyp (oder einem Array davon) sind, hat jede dieser Klassen einen trivialen Destruktor.

Soweit ich das beurteilen kann, ist die explizite Anforderung von PODness, auf Mitglieder anzuwenden, überflüssig, da sie sich implizit auch aus den Anforderungen ergibt, Standardlayout und trivial zu sein.

Eerorika
quelle