zjyhjqs
zjyhjqs

Reputation: 711

Define a static constexpr member of same type of a template class

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

Answers (1)

user12002570
user12002570

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

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

Related Questions