A variable declared constexpr
is implicitly const
and its value may be used as a constant expression.
Comparison with #define
A constexpr
is type-safe replacement for #define
based compile-time expressions. With constexpr
the compile-time evaluated expression is replaced with the result. For example:
int main()
{
constexpr int N = 10 + 2;
cout << N;
}
will produce the following code:
cout << 12;
A pre-processor based compile-time macro would be different. Consider:
#define N 10 + 2
int main()
{
cout << N;
}
will produce:
cout << 10 + 2;
which will obviously be converted to cout << 10 + 2;
. However, the compiler would have to do more work. Also, it creates a problem if not used correctly.
For example (with #define
):
cout << N * 2;
forms:
cout << 10 + 2 * 2; // 14
But a pre-evaluated constexpr
would correctly give 24
.
Comparison with const
A const
variable is a variable which needs memory for its storage. A constexpr
does not. A constexpr
produces compile time constant, which cannot be changed. You may argue that const
may also not be changed. But consider:
int main()
{
const int size1 = 10;
const int size2 = abs(10);
int arr_one[size1];
int arr_two[size2];
}
With most compilers the second statement will fail (may work with GCC, for example). The size of any array, as you might know, has to be a constant expression (i.e. results in compile-time value). The second variable size2
is assigned some value that is decided at runtime (even though you know it is 10
, for the compiler it is not compile-time).
This means that a const
may or may not be a true compile-time constant. You cannot guarantee or enforce that a particular const
value is absolutely compile-time. You may use #define
but it has its own pitfalls.
Therefore simply use:
int main()
{
constexpr int size = 10;
int arr[size];
}
A constexpr
expression must evaluate to a compile-time value. Thus, you cannot use:
constexpr int size = abs(10);
Unless the function (abs
) is itself returning a constexpr
.
All basic types can be initialized with constexpr
.
constexpr bool FailFatal = true;
constexpr float PI = 3.14f;
constexpr char* site= "StackOverflow";
Interestingly, and conveniently, you may also use auto
:
constexpr auto domain = ".COM"; // const char * const domain = ".COM"
constexpr auto PI = 3.14; // constexpr double