I think constexpr is a relatively advanced topic and there is often no
need to use it in most regular code.
Both const and constexpr can be used to define constants.
const just means that you are not allowed to modify the constant but it is not necessarily a compile-time constant because it might not be possible to calculate the value of the constant at compile-time.
Examle:
1 2 3 4 5
|
void foo(int a)
{
const int b = 2 * a;
...
}
|
In the above example b is a constant in the sense that it cannot be modified in the rest of the function, but it is not a compile-time constant because the value depends on what value that is being passed to the function so it is impossible to calculate the value at compile-time. It has to be calculated at runtime.
constexpr has the additional requirement that it has to be possible to calculate the value at compile-time. If this is not possible the compiler will give an error. This means you can only use other compile-time constants and constexpr functions when initializing the constexpr constant.
Examle:
1 2 3
|
constexpr int x = 3 * 10; // OK
constexpr int y = 3 * fun(10); // OK if fun is marked constexpr (and does not lead to an error internally)
constexpr int z = 3 * fun(e); // OK if fun is marked constexpr and e is also a compile-time constant
|
Compile-time constants are necessary in some situations, e.g. when specifying the size of a local array or when passing template arguments.
Examle:
1 2
|
constexpr int size = 10;
int arr[size]; // creates an array of size 10
|
This example would have worked even with const because const can sometimes also be used to create compile-time constants if the initialization expression fulfills the requirements for constexpr, but using constexpr makes the intention more clear, and would generate an error early if it fails to be a compile-time constant instead of later when you try to use it in a situation where a compile-time constant is required.