When we want to have a read-only object or promise not to change the value of some object in the current scope, we make it a constant. C++ uses the const type qualifier to mark the object as a read-only. We say that our object is now immutable. To define an integer constant with a value of 5, for example, we would write:
int main()
{
const int n = 5;
}
We can now use that constant in places such as an array size:
int main()
{
const int n = 5;
int arr[n] = { 10, 20, 30, 40, 50 };
}
Constants are not modifiable, attempt to do so results in a compile-time error:
int main()
{
const int n = 5;
n++; // error, can’t modify a read-only object
}
An object declared const cannot be assigned to; it needs to be initialized. So, we can’t have:
int main()
{
const int n; // error, no initializer
const int m = 123; // OK
}
Worth noticing is that const modifies an entire type, not just the object. So, const int and int are two different types. The first one is said to be const-qualified.
Another const qualifier is the constant expression named constexpr. It is a constant that can be evaluated at compile-time. Initializers for constant expressions can be evaluated at compile-time and must themselves be constant expressions. Example:
int main()
{
constexpr int n = 123; //OK, 123 is a compile-time constant // expression
constexpr double d = 456.78; //OK, 456.78 is a compile-time constant // expression
constexpr double d2 = d; //OK, d is a constant expression
int x = 123;
constexpr int n2 = x; //compile-time error
// the value of x is not known during // compile-time
}