Namespaces
Variants
Views
Actions

Type

From cppreference.com
< cpp‎ | language
Revision as of 01:43, 4 August 2018 by Cesar (Talk | contribs)

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
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
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

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

Type classification

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

  • the type bool;
  • character types:
  • narrow character types (char, signed char, unsigned char);
  • wide character types (char16_t, char32_t, wchar_t);
  • signed integer types (short int, int, long int, long long int);
  • unsigned integer types (unsigned short int, unsigned int, unsigned long int, unsigned long long int);
  • lvalue reference to object types;
  • lvalue reference to function types;
  • rvalue reference to object types;
  • rvalue reference to function types;

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

Types are grouped in various categories based on their properties:

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<int> v;       // declaration of a vector of int
sizeof(std::vector<int>); // type-id is "std::vector<int>"
 
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:

  • in the parameter list of a function (when the parameter name is omitted), type-id uses decl-specifier-seq instead of type-specifier-seq (in particular, some storage class specifiers are allowed);
  • in the name of a user-defined conversion function, 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 hidden by a non-type declaration. They may also be used to declare new class names.

See elaborated type specifier 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 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.

Incomplete type

The following types are incomplete types:

Any of the following contexts requires class 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.

See also