Reputation: 711
A similar question of non-templated class
For a template class,
template <typename T>
struct Test {
T data;
static const Test constant;
};
it's fine when defining a static constexpr
member variable of specialized type:
template <>
inline constexpr Test<int> Test<int>::constant {42};
https://godbolt.org/z/o4c4YojMf
While results are diverged by compilers when defining a static constexpr
member directly from a template class without instantiation:
template <typename T>
inline constexpr Test<T> Test<T>::constant {42};
https://godbolt.org/z/M8jdx3WzM
GCC
compiles.
clang
ignores the constexpr
specifier in definition.
MSVC
... /std:c++17
works well, but /std:c++20
rejects due to redefinition.
I have learnt that constexpr
can be applied to the definition a variable or variable template
And in this example, which one is right? Why?
Upvotes: 7
Views: 1023
Reputation: 1
I think GCC is correct in accepting the given example. This is because the static
data member named constant
is an ordinary data member variable(although it is still considered a templated entity).
And since constant
is an ordinary data member variable, dcl.constexpr#1.sentence-1 is applicable to it:
The constexpr specifier shall be applied only to the definition of a variable or variable template or the declaration of a function or function template.
(emphasis mine)
Thus, as the construct that you have provided after the class template is nothing but an out-of-class definition for the ordinary static data member constant
, the given example is well-formed.
template <typename T>
constexpr Test<T> Test<T>::constant {42}; //this is an out-of-class definition for the ordinary static data member variable `constant`
Note that dcl.constexpr#1.sentence-1 doesn't mention templated entity, but instead only mention "variable" and "variable template" and since constant
is a variable(ordinary), the same should be applicable to constant
.
Upvotes: 3