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.
    Also

    struct 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 member

    A 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.


  • Mod

    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.


  • Mod

    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 zu std::uint_least16_t (3.9.1/5)
    • char32_t - eigenständiger Typ, äquivalent zu std::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)

Anmelden zum Antworten