繁体   English   中英

是否在constexpr静态成员的声明中需要constexpr说明符在类外部初始化?

[英]Is the constexpr specifier required on the declaration of a constexpr static member initialized outside of the class?

C ++17§10.1.5/ 1指出:

constexpr说明符应仅适用于变量或变量模板的定义或函数或函数模板的声明。 使用constexpr说明符声明的函数或静态数据成员隐式地是内联函数或变量(10.1.6)。 如果函数或函数模板的任何声明都有constexpr说明符,那么它的所有声明都应包含constexpr说明符。

因为类似的段落已在标准中存在C ++ 11(§7.1.5/ 1),这是在引述由理查德·史密斯评论 ,其中他声称,C ++标准不需要 constexpr说明符之间匹配声明和变量的定义 在上段的最后一句明确要求constexpr符跨功能和函数模板声明匹配,但没有提到变量声明。

§10.1.5/ 9指出:

对象声明中使用的constexpr说明符将对象声明为const 这样的对象应具有文字类型并应初始化。 在任何constexpr变量声明中,初始化的完整表达式应为常量表达式(8.20)。

当然,如果我们有一个单独的声明和定义,他们都将需要匹配的const湖,无论是否constexpr符都需要相匹配。

§12.2.3.2/ 2-3说:

2在其类定义中声明非内联静态数据成员不是定义,除了cv void之外可能是不完整的类型。 未在类定义中内联定义的静态数据成员的定义应出现在包含成员类定义的命名空间范围内。 在命名空间作用域的定义中,静态数据成员的名称应使用::运算符通过其类名限定。 静态数据成员定义中的初始化表达式在其类的范围内(6.3.7)。

3如果非易失性非内联const静态数据成员具有整数或枚举类型...如果使用constexpr说明符声明该成员,则可以在没有初始化程序的命名空间范围内重新声明该成员(此用法已弃用;请参阅D 0.1)。 其他静态数据成员的声明不应指定大括号或等于初始化器

§D.1/ 1内容如下:

为了与先前的C ++国际标准兼容,可以在类外部冗余地重新声明constexpr静态数据成员而不使用初始化程序。 不推荐使用此用法。

从中我们可以收集到,如果使用constexpr说明符声明成员,则命名空间范围定义是多余的, 初始化表达式必须与声明配对,并且必须从定义 / 重新声明中省略。

为了作为一个完整的例子,我提供了一个自己的文字类型的静态成员的情况( 不能在类中初始化):

struct S
{
    static S const ZERO; // not marked `constexpr`, but still `const`

    constexpr S(int value = {}) : _value{ value } {}

    int const _value;
};

constexpr S S::ZERO{ 0 }; // implicitly `inline` (if C++17) and `const`

GCC,Clang和MSVC支持对constexpr与静态数据成员一起使用的解释,尽管我被告知这是错误的

跨变量声明和定义使用constexpr说明符不匹配是违反的吗?

如果这实际上是违规,则无法正确定义其自己的类的constexpr静态数据成员,因为类内定义是禁止的,因为类型不完整,并且禁止类外定义包含初始化程序如果类内声明用constexpr说明符标记。

如果我读这个:

static S const ZERO; // not marked `constexpr`, but still `const`

由于const S::ZERO永远不会在运行时更改其值。

然而:

constexpr S S::ZERO{ 0 }; // implicitly `inline` (if C++17) and `const`

S::ZERO进行Constant Evaluation ,对于_value ,它将具有常量整数值0
这将调用constexpr constructor

constexpr S(int value = {}) : _value{ value } {}

根据basic.start.static - 常量初始化

变量或临时对象的常量初始化器 o是一个初始化器,其full-expression是一个常量表达式 ,除非o是一个对象,这样的初始化器也可以调用o及其子对象的constexpr构造函数 ,即使这些对象是非对象的-literal类类型。

AND expr.const / 8.7 - 持续评估

一个变量,其名称显示为潜在的常量计算表达式,该表达式是constexpr变量或者是非易失性const限定的整数类型或引用类型。

因此:

跨变量声明和定义使用constexpr说明符不匹配是违反的吗?

我相信你的代码很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM