现在可以重新定义constexpr静态数据成员了吗? (但不是内联const)? [英] Redefinitions of constexpr static data members are allowed now? (but not inline const)?
问题描述
以下在c ++ 14中的gcc和clang下均无法编译,但在c ++ 1z中成功:
The following fails to compile under both gcc and clang in c++14, but succeeds with c++1z:
struct Cls {
static constexpr int N = 0;
};
constexpr int Cls::N;
constexpr int Cls::N;
C ++ 14错误是可预测的:'constexpr const int的定义Cls :: N'
The C++14 error is predictable: redefinition of ‘constexpr const int Cls::N’
为了使此法律合法而进行了哪些更改?我发现:
What changed to make this legal? I found:
n4659 10.1.5 [dcl.constexpr]
用constexpr
说明符声明的函数或静态数据成员隐式是内联函数或变量
A function or static data member declared with the constexpr specifier is implicitly an inline function or variable
所以我认为这可能与内联变量有关,但是在两个编译器下,对于c ++ 1z来说,以下操作均失败
So I thought it might have to do with inline variables, but the following fails for c++1z under both compilers
struct Cls {
static inline const int N = 0;
};
inline const int Cls::N; // note, only one definition here
推荐答案
在C +之前+17,您需要以一个翻译单元(通常每个翻译单元为 .cpp)重新声明类之外的所有
,因为以前允许(实际上是必需的)这样做,但是不赞成使用该语法。 static
变量。 code>文件,反之亦然,但这不是必需的)。正如您所指出的那样,C ++ 17引入了 inline
类成员变量,并且 static constexpr
变量自动合格。如您在第二个示例中所见,您不允许在类外重新声明内联
变量,但对<$ c $进行了例外处理c> constexpr
Before C++17, you needed to re-declare all static
variables outside the class in exactly one translation unit (typically each translation unit is a .cpp
file and vice versa, but this isn’t required). As you pointed out, C++17 introduces inline
class member variables, and static constexpr
variables automatically qualify. You are not allowed to redeclare inline
variables outside the class, as you saw in your second example, but an exception was made for constexpr
because previously you were allowed (and in fact required) to do so, but the syntax is deprecated.
在[class。 static.data] p2,它允许非内联成员使用语法(类定义中的非内联静态数据成员的声明不是定义,并且可能是
,而不是cv void以外的不完整类型在类定义中未在内联
中定义的静态数据成员的定义应出现在包含该成员的类定义的名称空间范围中。)
In [class.static.data]p2, it allows that syntax for non-inline members ("The declaration of a non-inline static data member in its class definition is not a definition and may be of an incomplete type other than cv void. The definition for a static data member that is not defined inline in the class definition shall appear in a namespace scope enclosing the member’s class definition.")
在下一段中,该标准允许 constexpr
类外声明,并要求它们用于非 constexpr
数据(
In the next paragraph, the standard allows constexpr
outside-of-class declarations and requires them for non-constexpr
data (emphasis added):
如果是非易失性非内联
const
静态数据成员是整体的或枚举类型,其在类定义中的声明
可以在
中指定一个
brace-or-equal-initializer ,每个 initializer-clause assignment-expression 是
常量表达式(8.20)。如果该成员在程序中使用(6.2),则仍应在
命名空间范围内定义该成员,并且
命名空间范围定义不应包含 initializer 。内联
静态数据成员可以在类定义
中定义,并且可以指定括号或相等初始化器。 如果成员是使用constexpr
声明符声明的
,则可以在
命名空间范围内重新声明它,而无需使用初始化程序(此操作已弃用;请参见
D.1)。其他静态数据成员的声明中不得指定
brace-or-equal-initializer 。
If a non-volatile non-inline
const
static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression (8.20). The member shall still be defined in a namespace scope if it is odr-used (6.2) in the program and the namespace scope definition shall not contain an initializer. 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 theconstexpr
specifier, it may be redeclared in namespace scope with no initializer (this usage is deprecated; see D.1). Declarations of other static data members shall not specify a brace-or-equal-initializer.
这是弃用说明,D.1重新声明静态constexpr数据成员[depr.static_constexpr]:
And here’s the deprecation note, D.1 Redeclaration of static constexpr data members [depr.static_constexpr]:
用于与先前的C ++兼容在国际标准中,可以在没有初始化程序的
类外部冗余地声明constexpr静态数据成员。不建议使用此用法。 [示例:
struct A {
static constexpr int n = 5; // definition (declaration in C++ 2014)
};
constexpr int A::n; // redundant declaration (definition in C++ 2014)
-结束示例]
这篇关于现在可以重新定义constexpr静态数据成员了吗? (但不是内联const)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!