定义同类型模板的静态 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 给出的示例中是正确的。这是因为名为 constant
的 static
数据成员是一个 普通数据成员变量(尽管它仍然被认为是一个 模板实体 ).
而由于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
.
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 给出的示例中是正确的。这是因为名为 constant
的 static
数据成员是一个 普通数据成员变量(尽管它仍然被认为是一个 模板实体 ).
而由于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
.