You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The keyword `constexpr` was introduced in C++11 and improved in C++14. It means *constant expression*. Like `const`, it can be applied to variables so that a compiler error will be raised if any code attempts to modify the value. Unlike `const`, `constexpr` can also be applied to functions and class constructors. `constexpr` indicates that the value, or return value, is constant and, if possible, will be computed at compile time. A `constexpr` integral value can be used wherever a const integer is required, such as in template arguments and array declarations. And when a value can be computed at compile time instead of run time, it can help your program run faster and use less memory.
21
-
22
-
## Syntax
23
-
24
-
```cpp
20
+
21
+
The keyword **constexpr** was introduced in C++11 and improved in C++14. It means *constant expression*. Like **const**, it can be applied to variables so that a compiler error will be raised if any code attempts to modify the value. Unlike **const**, **constexpr** can also be applied to functions and class constructors. **constexpr** indicates that the value, or return value, is constant and, if possible, will be computed at compile time.
22
+
23
+
A **constexpr** integral value can be used wherever a const integer is required, such as in template arguments and array declarations. And when a value can be computed at compile time instead of run time, it can help your program run faster and use less memory.
24
+
25
+
To limit the complexity of computing compile time constants, and their potential impacts of compilation time, the C++14 standard requires that the types involved in constant expressions be restricted to [literal types](trivial-standard-layout-and-pod-types.md#literal_types).
One or more parameters which must be a literal type (as listed below) and must itself be a constant expression.
34
-
35
-
## Return Value
36
-
A constexpr variable or function must return one of the literal types, as listed below.
37
-
38
-
## Literal types
39
-
To limit the complexity of computing compile time constants, and their potential impacts of compilation time, the C++14 standard requires that the types involved in constant expressions be restricted to literal types. A literal type is one whose layout can be determined at compile time. The following are the literal types:
40
-
41
-
1. void
42
-
43
-
2. scalar types
44
-
45
-
3. references
46
-
47
-
4. Arrays of void, scalar types or references
48
-
49
-
5. A class that has a trivial destructor, and one or more constexpr constructors that are not move or copy constructors. Additionally, all its non-static data members and base classes must be literal types and not volatile.
50
-
51
-
## constexpr variables
52
-
The primary difference between const and constexpr variables is that the initialization of a const variable can be deferred until run time whereas a constexpr variable must be initialized at compile time. All constexpr variables are const.
53
-
54
-
- A variable can be declared with `constexpr`, if it has a literal type and is initialized. If the initialization is performed by a constructor, the constructor must be declared as `constexpr`.
55
-
56
-
- A reference may be declared as constexpr if the object that it references has been initialized by a constant expression and any implicit conversions that are invoked during initialization are also constant expressions.
57
-
58
-
- All declarations of a `constexpr` variable or function must have the `constexpr` specifier.
59
-
60
-
61
-
62
-
63
-
64
-
```cpp
65
-
constexpr float x = 42.0;
66
-
constexpr float y{108};
67
-
constexpr float z = exp(5, 3);
68
-
constexpr int i; // Error! Not initialized
69
-
int j = 0;
70
-
constexpr int k = j + 1; //Error! j not a constant expression
71
-
```
72
-
73
-
## constexpr functions
74
-
A `constexpr` function is one whose return value can be computed at compile when consuming code requires it. When its arguments are `constexpr` values, and consuming code requires the return value at compile time, for example to initialize a `constexpr` variable or provide a non-type template argument, it produces a compile-time constant. When called with non-`constexpr` arguments, or when its value is not required at compile-time, it produces a value at run time like a regular function. (This dual behavior saves you from having to write `constexpr` and non-`constexpr` versions of the same function.)
75
-
76
-
A `constexpr` function or constructor is implicitly `inline`.
77
-
78
-
The following rules apply to constexpr functions:
33
+
constexpr ctor (params);
34
+
```
35
+
36
+
## Parameters
37
+
38
+
*params*
39
+
One or more parameters which must be a literal type and must itself be a constant expression.
40
+
41
+
## Return Value
79
42
80
-
- A `constexpr`function must accept and return only literal types.
43
+
A constexpr variable or function must return a [literal type](trivial-standard-layout-and-pod-types.md#literal_types).
81
44
82
-
- A `constexpr` function can be recursive.
45
+
## constexpr variables
46
+
47
+
The primary difference between const and constexpr variables is that the initialization of a const variable can be deferred until run time whereas a constexpr variable must be initialized at compile time. All constexpr variables are const.
48
+
49
+
- A variable can be declared with **constexpr**, if it has a literal type and is initialized. If the initialization is performed by a constructor, the constructor must be declared as **constexpr**.
50
+
51
+
- A reference may be declared as constexpr if the object that it references has been initialized by a constant expression and any implicit conversions that are invoked during initialization are also constant expressions.
52
+
53
+
- All declarations of a **constexpr** variable or function must have the **constexpr** specifier.
54
+
55
+
```cpp
56
+
constexprfloat x = 42.0;
57
+
constexprfloat y{108};
58
+
constexpr float z = exp(5, 3);
59
+
constexpr int i; // Error! Not initialized
60
+
int j = 0;
61
+
constexpr int k = j + 1; //Error! j not a constant expression
62
+
```
63
+
64
+
## constexpr functions
65
+
66
+
A **constexpr** function is one whose return value can be computed at compile when consuming code requires it. When its arguments are **constexpr** values, and consuming code requires the return value at compile time, for example to initialize a **constexpr** variable or provide a non-type template argument, it produces a compile-time constant. When called with non-**constexpr** arguments, or when its value is not required at compile-time, it produces a value at run time like a regular function. (This dual behavior saves you from having to write **constexpr** and non-**constexpr** versions of the same function.)
67
+
68
+
A **constexpr** function or constructor is implicitly **inline**.
69
+
70
+
The following rules apply to constexpr functions:
71
+
72
+
- A **constexpr** function must accept and return only [literal types](trivial-standard-layout-and-pod-types.md#literal_types).
73
+
74
+
- A **constexpr** function can be recursive.
83
75
84
76
- It cannot be [virtual](../cpp/virtual-cpp.md). A a constructor cannot be defined as constexpr if the enclosing class has any virtual base classes.
85
77
86
-
- The body can be defined as `= default` or `= delete`.
78
+
- The body can be defined as **= default** or **= delete**.
87
79
88
-
- The body can contain no `goto` statements or try blocks.
80
+
- The body can contain no **goto** statements or try blocks.
89
81
90
-
- An explicit specialization of a non-constexpr template can be declared as `constexpr`:
91
-
92
-
- An explicit specialization of a `constexpr` template does not have to also be `constexpr`:
82
+
- An explicit specialization of a non-constexpr template can be declared as **constexpr**:
93
83
84
+
- An explicit specialization of a **constexpr** template does not have to also be **constexpr**:
94
85
95
-
<!--conformance note-->
96
-
The following rules apply to constexpr functions in Visual Studio 2017 and later:
86
+
The following rules apply to **constexpr** functions in Visual Studio 2017 and later:
97
87
98
-
- It may contain if and switch statements, and all looping statements including for, range-based for, while, and do-while
99
-
88
+
- It may contain **if** and **switch** statements, and all looping statements including **for**, range-based for, **while**, and **do-while**.
89
+
100
90
- It may contain local variable declarations, but the variable must be initialized, must be a literal type, and cannot be static or thread-local. The locally-declared variable is not required to be const and may mutate.
101
91
102
92
- A constexpr non-static member function is not required to be implicitly const.
103
93
104
-
105
-
```cpp
106
-
constexprfloatexp(float x, int n)
107
-
{
108
-
return n == 0 ? 1 :
109
-
n % 2 == 0 ? exp(x * x, n / 2) :
110
-
exp(x * x, (n - 1) / 2) * x;
111
-
};
112
-
```
113
-
94
+
95
+
```cpp
96
+
constexpr float exp(float x, int n)
97
+
{
98
+
return n == 0 ? 1 :
99
+
n % 2 == 0 ? exp(x * x, n / 2) :
100
+
exp(x * x, (n - 1) / 2) * x;
101
+
};
102
+
```
103
+
114
104
> [!TIP]
115
-
> Note: In the Visual Studio debugger, you can tell whether a `constexpr` function is being evaluated at compile time by putting a breakpoint inside it. If the breakpoint is hit, the function was called at run-time. If not, then the function was called at compile time.
116
-
117
-
118
-
## Example
119
-
The following example shows `constexpr` variables, functions and a user-defined type. Note that in the last statement in main(), the `constexpr` member function GetValue() is a run-time call because the value is not required to be known at compile time.
cout << "The value of foo is " << foo.GetValue() << endl;
184
-
185
-
}
186
-
187
-
```
188
-
189
-
## Requirements
190
-
Visual Studio 2015
191
-
192
-
## See Also
193
-
[Declarations and Definitions](../cpp/declarations-and-definitions-cpp.md)
194
-
[const](../cpp/const-cpp.md)
105
+
> Note: In the Visual Studio debugger, when debugging a non-optimised Debug build, you can tell whether a **constexpr** function is being evaluated at compile time by putting a breakpoint inside it. If the breakpoint is hit, the function was called at run-time. If not, then the function was called at compile time.
106
+
107
+
## extern constexpr
108
+
109
+
The [/Zc:externConstexpr](../build/reference/zc-externconstexpr.md) compiler option causes the compiler to apply [external linkage]() to variables declared by using **extern constexpr**. In earlier versions of Visual Studio, and by default or if **/Zc:externConstexpr-** is specified, Visual Studio applies internal linkage to **constexpr** variables even if the **extern** keyword is used. The **/Zc:externConstexpr** option is available starting in Visual Studio 2017 Update 15.6. and is off by default. The /permissive- option does not enable /Zc:externConstexpr.
110
+
111
+
## Example
112
+
113
+
The following example shows **constexpr** variables, functions and a user-defined type. Note that in the last statement in main(), the **constexpr** member function GetValue() is a run-time call because the value is not required to be known at compile time.
Copy file name to clipboardExpand all lines: docs/cpp/cpp-type-system-modern-cpp.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,7 @@ The concept of *type* is very important in C++. Every variable, function argumen
36
36
37
37
The following example shows some simple variable declarations with some descriptions for each. The example also shows how the compiler uses type information to allow or disallow certain subsequent operations on the variable.
38
38
39
-
```
39
+
```cpp
40
40
41
41
int result = 0; // Declare and initialize an integer.
42
42
double coefficient = 10.8; // Declare and initialize a floating
@@ -83,7 +83,7 @@ int maxValue; // Not recommended! maxValue contains
83
83
## const type qualifier
84
84
Any built-in or user-defined type may be qualified by the const keyword. Additionally, member functions may be `const`-qualified and even `const`-overloaded. The value of a `const` type cannot be modified after it is initialized.
The first thing that you should know is declaring a raw pointer variable will allocate only the memory that is required to store an address of the memory location that the pointer will be referring to when it is dereferenced. Allocation of the memory for the data value itself (also called *backing store*) is not yet allocated. In other words, by declaring a raw pointer variable, you are creating a memory address variable, not an actual data variable. Dereferencing a pointer variable before making sure that it contains a valid address to a backing store will cause undefined behavior (usually a fatal error) in your program. The following example demonstrates this kind of error:
113
113
114
-
```
114
+
```cpp
115
115
116
116
int* pNumber; // Declare a pointer-to-int variable.
117
117
*pNumber = 10; // error. Although this may compile, it is
The example dereferences a pointer type without having any memory allocated to store the actual integer data or a valid memory address assigned to it. The following code corrects these errors:
125
125
126
-
```
126
+
```cpp
127
127
128
128
int number = 10; // Declare and initialize a local integer
However, it is easy to forget to delete a dynamically-allocated object- especially in complex code, which causes a resource bug called a *memory leak*. For this reason, the use of raw pointers is strongly discouraged in modern C++. It is almost always better to wrap a raw pointer in a [smart pointer](../cpp/smart-pointers-modern-cpp.md), which will automatically release the memory when its destructor is invoked (when the code goes out of scope for the smart pointer); by using smart pointers you virtually eliminate a whole class of bugs in your C++ programs. In the following example, assume `MyClass` is a user-defined type that has a public method `DoSomeWork();`
145
145
146
-
```
146
+
```cpp
147
147
148
148
voidsomeFunction() {
149
149
unique_ptr<MyClass> pMc(new MyClass);
@@ -174,4 +174,4 @@ void someFunction() {
174
174
## See Also
175
175
[Welcome Back to C++](../cpp/welcome-back-to-cpp-modern-cpp.md)
176
176
[C++ Language Reference](../cpp/cpp-language-reference.md)
177
-
[C++ Standard Library](../standard-library/cpp-standard-library-reference.md)
177
+
[C++ Standard Library](../standard-library/cpp-standard-library-reference.md)
0 commit comments