C++17 §10.1.5/1 states:
The
constexpr
specifier shall be applied only to the definition of a variable or variable template
If I were to read this:
static S const ZERO; // not marked `constexpr`, but still `const`
S::ZERO
will never change its value during run-time due to const
.
However:
constexpr S S::ZERO{ 0 }; // implicitly `inline` (if C++17) and `const`
Constant Evaluation
is done for S::ZERO
which will have constant integral value 0
for _value
.
This invokes your constexpr constructor
:
constexpr S(int value = {}) : _value{ value } {}
As per basic.start.static - Constant Initialization:
A constant initializer for a variable or temporary object
o
is an initializer whose full-expression is a constant expression, except that ifo
is an object, such an initializer may also invoke constexpr constructors foro
and its subobjects even if those objects are of non-literal class types.
AND expr.const/8.7 - Constant Evaluation:
a variable whose name appears as a potentially constant evaluated expression that is either a constexpr variable or is of non-volatile const-qualified integral type or of reference type.
Therefore:
Is it a violation to have non-matching use of the constexpr specifier across variable declarations and definitions?
I believe your code is fine.