This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-19
The status of an example like the following is not clear:
struct S { template <int N> static constexpr inline int m = N; }; template <> constexpr inline int S::m<5>;
Some implementations accept this, apparently on the basis of allowing and ignoring a redeclaration of a constexpr static data member outside its class, although there is implementation divergence. Most or all implementations, however, diagnose an attempt to use such a specialization in a constant context.
Should it be required to have a definition of the explicit specialization in order to declare it outside the class in such cases?
In addition, most or all implementations accept a version of the example in which the explicit specialization contains an initializer, including allowing its use in constant contexts:
template <> constexpr inline int S::m<5> = 2;
This would seem to be disallowed both by 11.4.9.3 [class.static.data] paragraph 3,
An inline static data member may be defined in the class definition and may specify a brace-or-equal-initializer. If the member is declared with the constexpr specifier, it may be redeclared in namespace scope with no initializer (this usage is deprecated; see _N4778_.D.4 [depr.static_constexpr]).
which prohibits an initializer, and 13.9.4 [temp.expl.spec] paragraph 2,
An explicit specialization may be declared in any scope in which the corresponding primary template may be defined (_N4868_.9.8.2.3 [namespace.memdef], 11.4 [class.mem], 13.7.3 [temp.mem]).
since the definition of a constexpr static data member is inside the class.
Notes from the May, 2019 teleconference:
These examples should behave in the same way as if the class were templated: instantiate the declaration and the definition of the static data member separately. The first example should be ill-formed, because the explicit specializaation does not have an initializer.