General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
Storage duration specifiers | ||||||||||||||||
Initialization | ||||||||||||||||
Expressions | ||||||||||||||||
Alternative representations | ||||||||||||||||
Literals | ||||||||||||||||
Boolean -Integer -Floating-point | ||||||||||||||||
Character -String -nullptr(C++11) | ||||||||||||||||
User-defined(C++11) | ||||||||||||||||
Utilities | ||||||||||||||||
Attributes(C++11) | ||||||||||||||||
Types | ||||||||||||||||
typedef declaration | ||||||||||||||||
Type alias declaration(C++11) | ||||||||||||||||
Casts | ||||||||||||||||
Memory allocation | ||||||||||||||||
Classes | ||||||||||||||||
Class-specific function properties | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
Objects,references,functions includingfunction template specializations, andexpressions have a property calledtype, which both restricts the operations that are permitted for those entities and provides semantic meaning to the otherwise generic sequences of bits.
Contents |
The C++ type system consists of the following types:
| (since C++11) |
| (since C++20) |
| (since C++11) |
| (since C++11) |
| (since C++23) |
| (since C++11) |
| (since C++11) |
For every non-cv-qualified type other than reference and function, the type system supports three additionalcv-qualified versions of that type (const,volatile, andconstvolatile).
Anobject type (see alsostd::is_object) is a (possibly cv-qualified) type that is not a function type, not a reference type, and not (possibly cv-qualified)void.
The following types are collectively calledscalar types (see alsostd::is_scalar):
(since C++11) |
The following types are collectively calledimplicit-lifetime types:
The following types are collectively calledtrivially copyable types:
The following types are collectively calledstandard-layout types:
| (since C++11) |
Type traits hierarchy diagram |
---|
Note: Elements of SVG image are clickable, but you must open the diagram in a new browser tab first |
The following types are collectively calledPOD types (see alsostd::is_pod):
| (deprecated in C++20) |
The following types are collectively calledtrivial types (see alsostd::is_trivial):
| (since C++11) (deprecated in C++26) |
Aprogram-defined specialization is anexplicit specialization orpartial specialization that is not part of the C++standard library and not defined by the implementation.
Aprogram-defined type is one of the following types:
| (since C++11) |
Aname can be declared to refer to a type by means of:
Types that do not have names often need to be referred to in C++ programs; the syntax for that is known astype-id. The syntax of the type-id that names typeT
is exactly the syntax of adeclaration of a variable or function of typeT
, with the identifier omitted, except thatdecl-specifier-seq of the declaration grammar is constrained totype-specifier-seq, 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.
int* p;// declaration of a pointer to intstatic_cast<int*>(p);// type-id is "int*" int a[3];// declaration of an array of 3 intnewint[3];// type-id is "int[3]" (called new-type-id) int(*(*x[2])())[3];// declaration of an array of 2 pointers to functions// returning pointer to array of 3 intnew(int(*(*[2])())[3]);// type-id is "int (*(*[2])())[3]" void f(int);// declaration of a function taking int and returning voidstd::function<void(int)> x= f;// type template parameter is a type-id "void(int)"std::function<auto(int)->void> y= f;// same std::vector<int> v;// declaration of a vector of intsizeof(std::vector<int>);// type-id is "std::vector<int>" struct{int x;} b;// creates a new type and declares an object b of that typesizeof(struct{int x;});// error: cannot define new types in a sizeof expressionusing t=struct{int x;};// creates a new type and declares t as an alias of that type sizeof(staticint);// error: storage class specifiers not part of type-specifier-seqstd::function<inlinevoid(int)> f;// error: neither are function specifiers
Thedeclarator part of the declaration grammar with the name removed is referred to asabstract-declarator.
Type-id may be used in the following situations:
sizeof
,alignof
,alignas
,new
, andtypeid
;(until C++17) |
Type-id can be used with some modifications in the following situations:
This section is incomplete Reason: 8.2[dcl.ambig.res] if it can be compactly summarized |
This section is incomplete Reason: mention and link to decltype and auto |
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 washidden by a non-type declaration. They may also be used to declare new class names.
Seeelaborated type specifier for details.
The type of an expression that results from the compile-time analysis of the program is known as thestatic type of the expression. The static type does not change while the program is executing.
If someglvalue expression refers to apolymorphic object, the type of its most derived object is known as the dynamic type.
// givenstruct B{virtual ~B(){}};// polymorphic typestruct D: B{};// polymorphic type D d;// most-derived objectB* ptr=&d; // the static type of (*ptr) is B// the dynamic type of (*ptr) is D
For prvalue expressions, the dynamic type is always the same as the static type.
The following types areincomplete types:
All other types are complete.
Any of the following contexts requires typeT
to be complete:
T
or argument typeT
;T
;T
;new
expression for an object of typeT
or an array whose element type isT
;T
;T
;dynamic_cast
, orstatic_cast
to typeT* orT&, except when converting from thenull pointer constant or from apointer to possibly cv-qualified void;T
;typeid
,sizeof
, oralignof
operator applied to typeT
;T
;T
;T
;T
,T&, orT*.(In general, when the size and layout ofT
must be known.)
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:
struct X;// declaration of X, no definition provided yetextern X* xp;// xp is a pointer to an incomplete type:// the definition of X is not reachable void foo(){ xp++;// ill-formed: X is incomplete} struct X{int i;};// definition of XX x;// OK: the definition of X is reachable void bar(){ xp=&x;// OK: type is “pointer to X” xp++;// OK: X is complete}
T
" and "array ofNT
") 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 atypedef
declaration permanently refers to an incomplete type. In either case, the array type cannot be completed:
externint arr[];// the type of arr is incompletetypedefint UNKA[];// UNKA is an incomplete type UNKA* arrp;// arrp is a pointer to an incomplete typeUNKA** arrpp; void foo(){ arrp++;// error: UNKA is an incomplete type arrpp++;// OK: sizeof UNKA* is known} int arr[10];// now the type of arr is complete void bar(){ arrp=&arr;// OK: qualification conversion (since C++20) arrp++;// error: UNKA cannot be completed}
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 328 | C++98 | class members of incomplete type were not prohibited if an object of the class type was never created | non-static class data members need to be complete |
CWG 977 | C++98 | the point when an enumeration type becomes complete in its definition was unclear | the type is complete once the underlying type is determined |
CWG 1362 | C++98 | user-defined conversions to typeT* orT& requiredT to be complete | not required |
CWG 2006 | C++98 | cv-qualifiedvoid types were object type and complete type | excluded from both categories |
CWG 2448 | C++98 | only cv-unqualified types could be integral and floating-point types | allows cv-qualified types |
CWG 2630 | C++98 | it was unclear whether a class is considered complete outside the translation unit where the definition of the class appears | the class is complete if its definition is reachable in this case |
CWG 2643 | C++98 | the type of a pointer to array of unknown bound could not be completed (but it is already complete) | the pointed-to array type cannot be completed |
LWG 2139 | C++98 | the meaning of “user-defined type” was unclear | defines and uses “program- defined type” instead |
LWG 3119 | C++11 | it was unclear whether closure types are program-defined types | made clear |
Type traits | A compile-time template-based interfaces to query the properties of types |
C documentation forType |
1. | Howard Hinnant's C++0x type tree |