定义同类型模板的静态 constexpr 成员class

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

A similar question of non-templated class

对于模板 class,

template <typename T>
struct Test {
    T data;

    static const Test constant;
};

定义一个static constexpr特殊类型的成员变量没问题:

template <>
inline constexpr Test<int> Test<int>::constant {42};

https://godbolt.org/z/o4c4YojMf


虽然在没有实例化的情况下直接从模板 class 定义 static constexpr 成员时编译器会产生不同的结果:

template <typename T>
inline constexpr Test<T> Test<T>::constant {42};

https://godbolt.org/z/M8jdx3WzM

GCC编译。
clang 忽略定义中的 constexpr 说明符。
MSVC.../std:c++17 运行良好,但 /std:c++20 由于重新定义而被拒绝。


我了解到constexpr can be applied to the definition a variable or variable template

在这个例子中,哪一个是正确的?为什么?

我认为 GCC 在 accepting 给出的示例中是正确的。这是因为名为 constantstatic 数据成员是一个 普通数据成员变量(尽管它仍然被认为是一个 模板实体 ).

而由于constant是一个普通的数据成员变量,所以dcl.constexpr#1.sentence-1适用于它:

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.

(强调我的)

因此,由于您在 class 模板之后提供的构造只不过是普通静态数据成员的 out-of-class 定义 constant,给出的例子是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`

备注

注意dcl.constexpr#1.sentence-1没有提到模板化实体,而是只提到“变量”和“变量模板”,因为constant是一个变量(普通),所以同样适用至 constant.