C++20 added two conse-related keywords, so there are currently four similar keywords: const, constexpr, consteval, and constinit.

Let’s discuss them separately.

First, a variable decorated with const has a read-only property and initialization occurs at run time. That is, if a variable is not allowed to be changed after its definition, it should be const. If you do not modify any member variables in a member function, you should add const after the member function.

However, it can also happen at compile time, such as when a const int is used instead of a macro to define an array size.

Second, variables or functions that are constEXPr modified are guaranteed to be read-only and to occur at compile time.

However, the function it modifies must occur at compile time only if the argument is constant and a compile-time constant is explicitly initialized with its return value. Such as:

#include <iostream>
 
 constexpr int sqr(int n) {
     return n * n;
 }
 
 
 int main() {
 
  // compile time
  static_assert(sqr(10) == 100);

  // compile time
  int array[sqr(10)];

  // compile time
  constexpr int res = sqr(10);

  // compile time or run time
  int tmp = sqr(10);

  // run time
  int a = 10;
  int tmp2 = sqr(a);
}
Copy the code

Here, the last two can occur at run time.

Third, Consteval is used to create an immediate function. Each call to the immediate function creates a compile-time constant.

Functions decorated with this keyword are automatically inline and cannot contain static data, or directives such as try, goto, or new, or call or use very large amounts of functions and data.

So, to put it simply, a consteval-modified function is bound to be parsed at compile time.

A quick example:

#include <iostream>
 
 int sqr1(int n) {
     return n * n;
 }
 
 constexpr int sqr2(int n) {
     return n * n;
 }

consteval int sqr3(int n) {
    return n * n;
}


int main() {

  //constexpr int res1 = sqr1(10); // error! run time
  constexpr int res2 = sqr2(10); // compile time
  constexpr int res3 = sqr3(10); // compile time

  int a = 10;
  int res4 = sqr1(a); // run time
  int res5 = sqr2(a); // run time
  //int res6 = sqr3(a); // error! compile time

}
Copy the code

There are three versions of SQR functions. Sqr1 () is undecorated, so it can only be called at runtime; Sqr2 () is constexpr and can occur at run time or compile time, depending on the argument passed in; Sqr3 () is decorated with consteval, so it must occur at compile time.

Therefore, any attempt to initialize a compile-time constant with the return value of a run-time function (SQR1), or to call a compile-time function (SQR3) with an infinitesimal parameter, will end in failure.

Fourth, constinit ensures that variables are initialized at compile time. These variables must be in static storage or thread storage.

Static store variables, which are global variables, static variables, or static member variables; Thread store variables, by which I mean thread_local modified variables, are local variables bound to the thread lifetime.

Here’s an example:

#include <iostream>
 
 constexpr int val1 = 100;
 constinit int val2 = 100;
 
 
 int main() {
 
   //std::cout << "++val1 " << ++val1 << '\n'; // error
  std::cout << "++val2 " << ++val2 << '\n';

  constexpr auto val3 = 100;
  //constinit auto val4 = 100; // error
  constinit thread_local auto val5 = 100;
}
Copy the code

As you can see on line 13, you cannot modify non-static local variables with constinit.

Variables decorated with constEXPr and constinit both exist at compile time. The difference is that constEXPr carries a read-only property, while CONSTinit does not.

Finally, draw a picture to sum up.

There are two dimensions, horizontal is runtime and vertical is read and write. Keywords are used to define the behavior of variables and functions in these two dimensions.

Since the four keywords were not introduced at the same time, const and CONSTexpr intersect. That is, const can also represent compile time, constExpr can also represent run time.

The two new keywords in C++20 apply to non-read-only compile-time variables and functions that must exist in either static storage or thread storage, and must be immediate function.

Finally, it is also very important to ask big gods when you encounter problems.I suggest joining this group to chatYou will also get a lot of help if you discuss with your predecessors. Can also exchange learning experience, technical problems, you can get PDF books source code, tutorials and so on for free use.