Type - cppreference.com (original) (raw)

Objects, references, functions including function template specializations, and expressions 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.

Contents

[edit] Type classification

The C++ type system consists of the following types:

the type char8_t (since C++20)
extended signed integer types (implementation-defined); (since C++11)
extended unsigned integer types (each corresponds to an extended signed integer type, and vice versa); (since C++11)
extended floating-point types (including cv-qualified versions): fixed width floating-point types; other implementation-defined extended floating-point types; (since C++23)
  1. signed char and unsigned char are narrow character types, but they are not character types. In other words, the set of narrow character types is not a subset of the set of character types.

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

[edit] Other categories

An object type (see also std::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 called scalar types (see also std::is_scalar):

The following types are collectively called implicit-lifetime types:

The following types are collectively called trivially copyable types: scalar types trivially copyable class types arrays of such types cv-qualified versions of these types The following types are collectively called standard-layout types: scalar types standard-layout class types arrays of such types cv-qualified versions of these types (since C++11)
Type traits hierarchy diagram
cpp types v3.svg Note: Elements of SVG image are clickable, but you must open the diagram in a new browser tab first

[edit] Deprecated categories

The following types are collectively called POD types (see also std::is_pod): scalar types POD classes arrays of such types cv-qualified versions of these types (deprecated in C++20)
The following types are collectively called trivial types (see also std::is_trivial): scalar types trivial class types arrays of such types cv-qualified versions of these types (since C++11)(deprecated in C++26)

[edit] Program-defined type

A program-defined specialization is an explicit specialization or partial specialization that is not part of the C++ standard library and not defined by the implementation.

A program-defined type is one of the following types:

[edit] Type naming

A name 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 as type-id. The syntax of the type-id that names type T is exactly the syntax of a declaration of a variable or function of type T, with the identifier omitted, except that decl-specifier-seq of the declaration grammar is constrained to type-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 int static_cast<int*>(p); // type-id is "int*"   int a[3]; // declaration of an array of 3 int new int[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 int new (int (([2])())[3]); // type-id is "int (([2])())[3]"   void f(int); // declaration of a function taking int and returning void std::function<void(int)> x = f; // type template parameter is a type-id "void(int)" std::function<auto(int) -> void> y = f; // same   std::vector v; // declaration of a vector of int sizeof(std::vector); // type-id is "std::vector"   struct { int x; } b; // creates a new type and declares an object b of that type sizeof(struct { int x; }); // error: cannot define new types in a sizeof expression using t = struct { int x; }; // creates a new type and declares t as an alias of that type   sizeof(static int); // error: storage class specifiers not part of type-specifier-seq std::function<inline void(int)> f; // error: neither are function specifiers

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

Type-id may be used in the following situations:

Type-id can be used with some modifications in the following situations:

[edit] 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 hidden by a non-type declaration. They may also be used to declare new class names.

See elaborated type specifier for details.

[edit] 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.

[edit] Dynamic type

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

// given struct B { virtual ~B() {} }; // polymorphic type struct D : B {}; // polymorphic type   D d; // most-derived object B* 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.

[edit] Incomplete type

The following types are incomplete types:

All other types are complete.

Any of the following contexts requires type T to be complete:

(In general, when the size and layout of T 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 yet extern 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 X X x; // OK: the definition of X is reachable   void bar() { xp = &x; // OK: type is “pointer to X” xp++; // OK: X is complete }

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 typedef declaration permanently refers to an incomplete type. In either case, the array type cannot be completed:

extern int arr[]; // the type of arr is incomplete typedef int UNKA[]; // UNKA is an incomplete type   UNKA* arrp; // arrp is a pointer to an incomplete type UNKA** 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 }

[edit] Defect reports

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 prohibitedif an object of the class type was never created non-static class data membersneed to be complete
CWG 977 C++98 the point when an enumeration type becomescomplete in its definition was unclear the type is complete once theunderlying type is determined
CWG 1362 C++98 user-defined conversions to type T* or T& required T to be complete not required
CWG 2006 C++98 cv-qualified void 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 outsidethe translation unit where the definition of the class appears the class is completeif its definition isreachable in this case
CWG 2643 C++98 the type of a pointer to array of unknown boundcould not be completed (but it is already complete) the pointed-to array typecannot 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

[edit] References

[edit] See also