Consider the code
#include <iostream>
struct Foo
{
constexpr static int n = 42;
};
const int Foo::n; // note const, NOT constexpr
int main()
{
std::cout << Foo::n;
}
The definition of the static member is different from the in-class declaration, i.e. const
is used instead of constexpr
. Is the code above legal, and if yes, why? It compiles with both gcc and clang. It also compiles if we interchanged const
and constexpr
in the definition and declaration, respectively. I know that constexpr
implies const
on variables, but not the other way around.
#define directives create macro substitution, while constexpr variables are special type of variables. They literally have nothing in common beside the fact that before constexpr (or even const ) variables were available, macros were sometimes used when currently constexpr variable can be used.
The primary difference between const and constexpr variables is that the initialization of a const variable can be deferred until run time. A constexpr variable must be initialized at compile time.
A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later. So, what does constexpr mean?
constexpr stands for constant expression and is used to specify that a variable or function can be used in a constant expression, an expression that can be evaluated at compile time. The key point of constexpr is that it can be executed at compile time.
My two cents, while looking at some documentation like that one.
Actually, it could be valid.
In fact, the difference between constexpr
and const
mainly relies into their purposes, but the former implies the latter as a side effect.
There is also a more subtle difference: constexpr
is a specifier, while const
is a type qualifier.
In particular:
const’s primary function is to express the idea that an object is not modified through an interface
On the other side:
constexpr’s primary function is to extend the range of what can be computed at compile time, making such computation type safe and also usable in compile-time contexts
Or even more concise from here:
constexpr - specifies that the value of a variable or function can appear in constant expressions
Anyway it happens that:
constexpr in front of a variable definition [...] implies const
So, even though the reason for which one should use constexpr
instead of const
is clear, and everybody tends to remember that:
constexpr is not a general purpose replacement for const (or vice versa)
It's a fact that using constexpr
you are actually saying that this member is implicitly const
(also you have a set of more specific constraints on how that member can be defined).
Anyway, once defined, the member is nothing more than a data member having the const
type qualifier (which can be used in constant expressions), that is what you are declaring out of your class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With