没有初始化程序的constexpr静态数据成员 [英] constexpr static data member without initializer
问题描述
#include <complex>
struct S
{
static std::complex<double> constexpr c;
};
gcc生成错误,因为缺少初始化程序. Clang和MSVC不会产生错误.
gcc generates an error because an initializer is missing. Clang and MSVC do not generate an error.
据我所知,constexpr静态数据成员必须具有初始化程序,即使它是具有可不带参数调用的构造函数的类类型(在这种情况下).不幸的是,我没有最新的C ++标准来支持我的假设.
As far as I know a constexpr static data member must have an initializer, even if it is of class type that has a constructor that can be called without arguments (as in this case). Unfortunately I don't have the latest C++ standard to back up my assumption.
因此正确的代码应使用构造函数进行初始化,例如:
So the correct code should initialize with a constructor, for instance:
struct S
{
static std::complex<double> constexpr c {};
};
谁能证明哪个编译器是正确的,哪个是错误的?
Can anyone prove which compiler is right and which is wrong?
推荐答案
GCC错误.
GCC对constexpr
变量使用C ++ 14规则,这需要提供一个初始化程序.每个 P0386 (粗体是新添加的文本):
GCC uses the C++14 rules for constexpr
variables, which requires an initializer to be provided. This is changed per P0386 (bold text is newly added text):
在9.2.3.2p3中,更改:
如果非易失性 n-in-inline const静态数据成员是整数或枚举类型,则其在类定义中的声明可以指定ab race-or-equal -initializer ,其中每个 assignment-expression 的 initializer-clause 都是一个常数表达式(5.20). 可以使用constexpr说明符在类定义中声明文字类型的静态数据成员;如果是这样,则其声明应指定一个括号等于相等的初始化程序,其中作为赋值表达式的每个初始化程序子句都是一个常量表达式. [注意:在这两种情况下,该成员都可能出现在常量表达式中. -end note] 如果在程序中使用了成员(3.2),则该成员仍应在名称空间范围中定义,并且该名称空间范围定义不应包含初始化程序.静态数据成员可以在类定义中定义,并且可以指定 b种族或相等初始化器.如果使用constexpr说明符声明了该成员,则可以在命名空间范围内使用以下内容重新声明该成员:没有初始化程序(不建议使用此用法;请参见DX).其他静态数据成员的声明中不应指定 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 (5.20). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. — end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer. An inline static data member can be defined in the class definition and may specify a brace-or-equal-initializer. If the member is declared with the constexpr specifier, it may be redeclared in namespace scope with no initializer (this usage is deprecated; see D.X). Declarations of other static data members shall not specify a brace-or-equal-initializer.
这篇关于没有初始化程序的constexpr静态数据成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!