static_assert(std::is_pod<T>::value, "T kein POD"); failed
-
class T { public: T() : m(0) {} T(int h) : m(h) {} private: int m; }; static_assert(std::is_pod<T>::value, "T kein POD");
Dieses static_assert failed bei g++ 4.8.1. Ist das richtig? Wie kann ich T zu einem POD machen?
-
Da ist die Definition von POD: http://www.c-plusplus.net/forum/194356
Um T einen POD zu machen muss recht viel geändert werden: m muss public sein, Konstruktoren müssen weg.
Alsostruct T { int m; };
-
Ich meine im neuesten Stroustrup gelesen zu haben, dass PODs in C++11 auch bestimmte Konstruktoren haben dürfen?
-
In der Tat, den Konstruktor ohne Argumente kann ich lassen.
-
Seit C++11:
§9/10 schrieb:
A POD struct is a non-union class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types).
A standard-layout class is a class that:
— has no non-static data members of type non-standard-layout class (or array of such types) or reference,
— has no virtual functions (10.3) and no virtual base classes (10.1),
— has the same access control (Clause 11) for all non-static data members,
— has no non-standard-layout base classes,
— either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
— has no base classes of the same type as the first non-static data memberA trivial class is a class that has a trivial default constructor (12.1) and is trivially copyable.
A trivially copyable class is a class that:
— has no non-trivial copy constructors (12.8),
— has no non-trivial move constructors (12.8),
— has no non-trivial copy assignment operators (13.5.3, 12.8),
— has no non-trivial move assignment operators (13.5.3, 12.8), and
— has a trivial destructor (12.4).Und jetzt kommt der Part, wo
POD schrieb:
In der Tat, den Konstruktor ohne Argumente kann ich lassen.
widerlegt wird:
A default constructor is trivial if it is not user-provided [...]
dass PODs in C++11 auch bestimmte Konstruktoren haben dürfen?
Nein, das ist falsch. Denn sobald du irgendeinen Konstruktor definierst, kann der Default-Konstruktor nicht mehr trivial sein.
campers Definition müsste demnach angepasst werden.
-
poddle schrieb:
Da ist die Definition von POD: http://www.c-plusplus.net/forum/194356
Da scheint mir ein Fehler unterlaufen zu sein (zuviel aus der C++03 kopiert). (ich glaube mich zu erinnern, die Liste schon mal etwas überarbeitet zu haben, wurde offenbar nicht in die FAQ verschoben).
m muss nicht public sein, es muss nur für alle nichtstatischen Daten-Member die gleiche Zugriffskontrolle gegeben sein (evident gegeben bei nur einem Member).Der Defaultkonstruktor muss trivial sein.
class T { public: T() = default; T(int h) : m(h) {} private: int m; }; static_assert(std::is_pod<T>::value, "T kein POD");
-
Danke, camper.
-
Hier mal eine aktualisierte Version (hatte offenbar tatsächlich vergessen, die POD-Definition zu überarbeiten)
Unterpunkte sind sich ausschließende Alternativen, soweit nicht anders gekennzeichnet.
Alle Typen
- Fundamentale Typen (fundamental types 3.9.1)
- arithmetische Typen (arithmetic types 3.9.1/8)
- integrale Typen (integral types / integer types 3.9.1/7)
- vorzeichenbehaftete integrale Typen (signed integer types 3.9.1/2)
- vorzeichenbehaftet integrale Standardtypen (standard signed integer types 3.9.1/2)
signed char
short int
int
long int
long long int
- erweiterte vorzeichenbehaftete Integer (extended signed integer types 3.9.1/2) - optional (implementation-defined)
- vorzeichenlose integrale Typen (unsigned integral types 3.9.1/3)
- vorzeichenlose integrale Standardtypen (standard unsigned integer types 3.9.1/3)
unsigned char
unsigned short int
unsigned int
unsigned long int
unsigned long long int
- erweiterte vorzeichenbehaftete Integer (extended unsigned integer types 3.9.1/3) - optional (implementation-defined)
- andere
bool
- ist vorzeichenlos, gehört aber nicht zu dieser Kategorie und braucht ein paar Sonderregeln (3.9.1/6)char
- verhält sich implementationsabhängig entweder wie signed char oder unsigned char (3.9.1/1)wchar_t
- verhält sich implementationsabhängig wie ein bestimmter vorzeichenloser oder vorzeichenbehafteter integraler Typ (3.9.1/5)char16_t
- eigenständiger Typ, äquivalent zustd::uint_least16_t
(3.9.1/5)char32_t
- eigenständiger Typ, äquivalent zustd::uint_least32_t
(3.9.1/5)- Gleitkommatypen (floating point types 3.9.1/8)
float
double
long double
void
(3.9.1/9)std::nullptr_t
(3.9.1/10)- Zusammengesetzte Typen (compound types 3.9.2)
- Arrays (arrays)
- Funktionen (function types)
- Zeiger (pointer types)
- Objektzeiger (object pointer types 3.9.2/3)
- Zeiger auf Objekte (pointer to object types)
- Zeiger auf void (pointer to void)
- Funktionszeiger (function pointer types 3.9.2/3)
- Referenzen (references)
- lvalue-Referenzen (lvalue references)
- rvalue-Referenzen (rvalue references)
- Klassen (classes)
union
- Strukturen (structs)
struct
class
- Aufzählungen (enumerations) (s.u.)
- Zeiger auf nicht-statische Member (pointer to (non-static) class member)
Zeichentypen (character types)
char
signed char
unsigned char
Objekttypen (object types 3.9/8)
- alle außer void, Referenzen, Funktionen
Skalare Typen (scalar types) - alle Objekttypen, die keine Komponenten haben
- arithmetische Typen
std::nullptr_t
- Zeiger
- Zeiger auf Member
- Aufzählungen
Aufzählungen (enumerations)
- unscoped enumerations (enum-key =
enum
) - Aufzählungskonstanten werden im gleichen Scope wie die Aufzählung selbst plaziert - scoped enumerations (enum-key =
enum class
/enum struct
) - Aufzählung bildet einen eigenen Scope, in dem sich die Aufzählungskonstanten befinden, keine implizite Konvertierung in integer
Aufzählungstypen haben einen zugrundeliegenden integralen Typen (underlying type), der für die Repräsentation verwendet werden kann.
Dieser kann explizit angegeben werden (enum-base), wird er nicht angegeben, so ist er int im Falle von scoped Aufzählungen. In diesen Fällen ist der zugrundeliegende Typ fest (fixed).
Im Falle von unscoped Aufzählungen ohne Angabe ist der Typ unspezifiziert mit bestimmten Einschränkungen (Details in 7.2/6), in der Praxis typischerweise int oder - soweit erforderlich - ein größerer Typ.Aggregate (aggregates)
- Arrays
- Klassen, die
- keine vom Nutzer deklarierte Konstruktoren haben, und
- keine nicht-statischen protected oder private Datenmember haben, und
- keine Basisklassen haben, und
- keine virtuelle Funktionen haben, und
- keine Initialisierer für nichtstatische Member haben
POD (plain old data)
- Skalare Typen
- Klassen, die
- trivial sind, und
- Standardlayout haben, und
- keine nichtstatischen nicht-POD-Datenmember haben
- Arrays aus PODs
Alle POD-Typen sind trivial und haben Standard-Layout.
Literaltypen (literal types)
- Skalare Typen
- Referenzen auf Literaltypen
- Array aus Literalen
- Klassen
- mit trivialen Destruktor, und
- vorhandene Initialisierer für nichtstatische Member sind konstante Ausdrücke bzw. Listen aus solchen Ausdrücken, und
- alle nichtstatischen Datenmember und Basisklassen sind Literaltypen, und
- Klasse
- ist Aggregat
- hat mindestens einen constexpr-Konstruktor, der kein Copy- oder Movekonstruktor ist
Trivial kopierbare Typen (trivially copyable types 3.9/9)
- Skalare Typen
- Klassen
- ohne nicht-trivialen Copy-Konstruktor, und
- ohne nicht-trivialen Move-Konstruktor, und
- ohne nicht-trivialen Copy-Zuweisungsoperator, und
- ohne nicht-trivialen Move-Zuweisungsoperator, und
- mit trivialem Destruktor
- Arrays trivial kopierbarer Typen
Triviale Typen (trivial types 3.9/9)
- Skalare Typen
- Triviale Klassen, das sind
- trivial kopierbare Klassen mit
- trivialem Defaultkonstruktor
- Arrays trivialer Typen
Alle trivialen Typen sind trivial kopierbar.
Standardlayout-Typen (standard-layout types)
- Skalare Typen
- Standardlayout Klassen
- nichtstatische Daten-Member haben Standardlayout, und
- Basisklassen haben Standardlayout, und
- keine virtuellen Funktionen, und
- keine virtuellen Basisklassen, und
- gleiche Zugriffskontrolle für alle nichstatischen Datenmember, und
- höchtens 1 Klasse in der gesamten Vererbungshierarchie definiert nichtstatische Daten-Member, und
- 1. Daten-Member (wenn vorhanden) ist nicht gleichzeitig Basisklasse
- Arrays aus Standardlayout-Typen
UDT (user defined types)
- Klassen
- Aufzählungen
eingebaute Typen (build-in types)
- Typen, die keine UDTs sind
Triviale Memberfunktionen
---------------------------------
Eine spezielle Memberfunktion ist user-provided, wenn sie explizit deklariert wird, und diese 1. Deklaration weder explizit defaulted noch explizit deleted ist.
Zur Vereinfachung im Folgenden:
Eine Subobjektklasse sei eine Klasse, bei der es sich entweder um eine (direkte) Basisklasse oder den Klassentyp eines nichtstatischen Members, oder den Klassentype eines Elementes eines nichtstatischen Memberarrays handelt.Eine spezielle Memberfunktion ist trivial, wenn
- sie nicht user-provided ist, und
- korrespondierende Memberfunktionen aller Subobjektklassen trivial sind, und
- im Falle des Defaultkonstruktors kein nichtstatischer Member über einen Initialisierer verfügt, und
- im Falle des Destruktors dieser nicht virtuell ist
- die Klasse keine virtuellen Funktionen und keine virtuellen Basisklassen hat
Korrespondierende Memberfunktionen i.o.S. sind
- im Falle eines Defaultkonstruktors die Defaultkonstruktoren der Subobjektklassen
- im Falle des Destruktors die Destruktoren der Subobjektklassen
- sonst die Memberfunktionen, die für Copy-/Move der Subobjekte ausgewählt werden (dabei handelt es sich nicht notwendigerweise um Copy-/Move-Konstruktoren oder Zuweisungsoperatoren, allerdings können nur solche trivial sein)