C++17 §10.1.5/1 states:
The
constexprspecifier 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
ois an initializer whose full-expression is a constant expression, except that ifois an object, such an initializer may also invoke constexpr constructors foroand 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.