cpp/language/type

, s, including, and  have a property called type, which both restricts the operations that are permitted for those entities and provides semantic meaning to the otherwise generic sequences of bits.

Type classification
The C++ type system consists of the following types:
 * (see also std):
 * the type (see also std);


 * arithmetic types (see also std):
 * integral types / integer types (including, see also std):
 * the type ;
 * character types:
 * narrow character types:
 * ordinary character types


 * wide character types ;
 * signed integer types:
 * standard signed integer types ;


 * unsigned integer types:
 * standard unsigned integer types ;


 * floating-point types (see also std):
 * standard floating-point types (,, and their );


 * compound types (see also std):
 * (see also std):
 * (see also std):
 * lvalue reference to object types;
 * lvalue reference to function types;


 * (see also std):
 * (see also std):
 * types (see also std);
 * types (see also std);
 * (see also std);
 * (see also std);
 * (see also std);
 * (see also std);
 * (see also std);


 * non-union types (see also std);
 * (see also std).
 * (see also std).

For every non-cv-qualified type other than reference and function, the type system supports three additional of that type (,, and ).

Types are grouped in various categories based on their properties:
 * object types are (possibly cv-qualified) types that are not function types, reference types, or possibly cv-qualified (see also std);
 * scalar types are (possibly cv-qualified) object types that are not array types or class types (see also std);
 * trivial types (see also std), POD types (see also std), literal types (see also std), and other categories listed in the type traits library or as named type requirements.

Constructing a complete object type such that the number of bytes in its object representation is not representable in the type std (i.e. the result type of operator) is ill-formed.

Type naming
A can be declared to refer to a type by means of:
 * declaration;
 * declaration;
 * declaration;
 * declaration;
 * declaration.

Types that do not have names often need to be referred to in C++ programs; the syntax for that is known as. The syntax of the type-id that names type is exactly the syntax of a  of a variable or function of type, with the identifier omitted, except that  of the declaration grammar is constrained to , and that new types may be defined only if the type-id appears on the right-hand side of a non-template type alias declaration.

The part of the declaration grammar with the name removed is referred to as.

Type-id may be used in the following situations:
 * to specify the target type in ;
 * as arguments to, , , , and ;
 * on the right-hand side of a declaration;
 * as the trailing return type of a declaration;
 * as the default argument of a ;
 * as the template argument for a ;

Type-id can be used with some modifications in the following situations:
 * in the parameter list of a (when the parameter name is omitted), type-id uses  instead of  (in particular, some storage class specifiers are allowed);
 * in the name of a, the abstract declarator cannot include function or array operators.

Elaborated type specifier
Elaborated type specifiers may be used to refer to a previously-declared class name (class, struct, or union) or to a previously-declared enum name even if the name was. They may also be used to declare new class names.

See for details.

Static type
The type of an expression that results from the compile-time analysis of the program is known as the static type of the expression. The static type does not change while the program is executing.

Dynamic type
If some refers to a, the type of its most derived object is known as the dynamic type.

For prvalue expressions, the dynamic type is always the same as the static type.

Incomplete type
The following types are incomplete types: All other types are complete.
 * the type (possibly -qualified);
 * incompletely-defined object types:
 * class type that has been declared (e.g. by ) but not defined;
 * array of elements of incomplete type;
 * from the point of declaration until its underlying type is determined.
 * from the point of declaration until its underlying type is determined.

Any of the following contexts requires type to be complete: (In general, when the size and layout of must be known.)
 * of or call to a function with return type or argument type ;
 * of an object of type ;
 * declaration of a of type ;
 * for an object of type or an array whose element type is ;
 * applied to a glvalue of type ;
 * an or  conversion to type ;
 * a, , or to type  or , except when converting from the  or from a ;
 * applied to an expression of type ;
 * ,, or operator applied to type ;
 * applied to a pointer to ;
 * definition of a class with base class ;
 * assignment to an lvalue of type ;
 * a for an exception of type, , or.

If any of these situations occur in a translation unit, the definition of the type must appear in the same translation unit. Otherwise, it is not required.

An incompletely-defined object type can be completed:


 * A class type (such as ) might be regarded as incomplete at one point in a translation unit and regarded as complete later on; the type is the same type at both points:


 * The declared type of an array object might be an array of incomplete class type and therefore incomplete; if the class type is completed later on in the translation unit, the array type becomes complete; the array type at those two points is the same type.


 * The declared type of an array object might be an array of unknown bound and therefore be incomplete at one point in a translation unit and complete later on; the array types at those two points ("array of unknown bound of " and "array of ") are different types.

The type of a pointer or reference to array of unknown bound permanently points to or refers to an incomplete type. An array of unknown bound named by a declaration permanently refers to an incomplete type. In either case, the array type cannot be completed: