POD is Plain Old Data. In C++, it refers to objects that can be treated as “data only,” where programmers do not need to worry about the complexity of class layout, as well as user-defined constructors, copy, and move semantics.
Before introducing what POD is, it is essential to understand the following concepts.
Scalar types
Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), std::nullptr_t, and cv-qualified versions of these types (3.9.3) are collectively called scalar types.
standard-layout types
Scalar types, standard-layout class types (Clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called standard-layout types. (ISO/IEC 14882:2014(E) §3.9.1 P71)
standard-layout class
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. (This ensures that two subobjects that have the same class type and that belong to the same most derived object are not allocated at the same address)
In simpler terms, a type has a standard layout if it must not have the following properties:
- Contains a non-standard layout non-static member or base class
- Contains virtual functions
- Contains virtual base classes
- Contains member of reference type
- Has non-static data members with multiple access specifiers (public/private/protected)
- Prevents important layout optimizations
- Contains non-static data members in multiple base classes, or contains non-static data members in both the derived class and base class
- Has a base class type that is the same as the type of the first non-static data member
Essentially, standard-layout types are those that are compatible with C language layout and should be able to be handled by the regular C++ ABI (Application Binary Interface).
std::is_standard_layout
The standard library provides std::is_standard_layout
to determine whether a type is a standard layout, defined in type_traits
.
1 | template< class T > |
Member constants | |
---|---|
value [static] | true if T is a standard-layout type, false otherwise |
Member functions | |
operator bool | converts the object to bool , returns value (public member function) |
operator() (C++14) | returns value (public member function) |
Member types | |
Type | Definition |
value_type | bool |
type | std::integral_constant<bool , value > |
1 |
|
trivially copyable types
Cv-unqualified scalar types, trivially copyable class types (Clause 9), arrays of such types, and non-volatile const-qualified versions of these types (3.9.3) are collectively called trivially copyable types. (ISO/IEC 14882:2014(E) §3.9.1 P71)
trivially copyable class
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).
A trivial class is a class that has a default constructor (12.1), has no non-trivial default constructors, and is trivially copyable. [Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes. — end note] (ISO/IEC 14882:2014(E) §9 P215)
Unless a type contains non-trivial copy, move, or destructor operations internally, it is considered a trivially copyable type. Built-in type variables are all trivially copyable and have standard layout. Similarly, arrays composed of trivially copyable objects are trivially copyable, and arrays comprised of standard layout objects have standard layout.
POD types
Scalar types, POD classes (Clause 9), arrays of such types, and cv-qualified versions of these types (3.9.3) are collectively called POD types.
POD must belong to the following types of objects:
- Standard layout types (standard-layout types)
- Trivially copyable types (trivially copyable type)
Thus, if we want to treat an object as “data only” (POD), the object must satisfy the following conditions:
- Does not have a complex layout (for example, contains a vptr)
- Does not have non-standard (user-defined) copy semantics
- Contains a most trivial (trivial) default constructor
trivial default constructor: a default constructor is trivial if it does not need to do any work (use =default if you need to define one). (TC++PL4E(E) §8.2.6 P211)
It should be noted that adding or removing non-default constructors will not affect the layout and performance (this was not the case in C++98).
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). Similarly, a POD union is a union 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 POD class is a class that is either a POD struct or a POD union. (ISO/IEC 14882:2014(E) §9.1 P216)
1 | struct N { // neither trivial nor standard-layout |
Now consider the following code:
1 | struct s0{}; // is POD |
std::is_pod
You can use std::is_pod
to determine whether a type is a POD type. std::is_pod
is a standard library type trait predicate defined in type_traits
, with the same usage, member functions, and member types as std::is_standard_layout
.
1 | template< class T > |
1 | int main() |