繁体   English   中英

类型为double的静态类成员的常量表达式初始值设定项

[英]Constant expression initializer for static class member of type double

在C ++ 11和C ++ 14中,为什么我需要在以下代码段中使用constexpr

class Foo {
    static constexpr double X = 0.75;
};

而这个产生编译错误:

class Foo {
    static const double X = 0.75;
};

(更令人惊讶的是)这个编译没有错误?

class Foo {
    static const double X;
};

const double Foo::X = 0.75;

在C ++ 03中,我们只允许为枚举类型的const积分的静态成员变量提供类初始化器,在C ++ 11中,我们可以使用constexpr在类中初始化文本类型的静态成员。 对于const变量,这个限制保留在C ++ 11中,主要是为了兼容性C ++ 03我们可以从封闭的问题1826看到这一点:常量表达式中的const浮点数表示:

用常量初始化的const整数可以用在常量表达式中,但是用常量初始化的const浮点变量不能。 这是故意的,与C ++ 03兼容,同时鼓励constexpr的一致使用。 然而,有些人发现这种区别令人惊讶。

CWG最终以非缺陷( NAD )结束此请求,基本上说:

希望浮点值参与常量表达式的程序员应该使用constexpr而不是const。

作为参考N1804 ,第9.4.2[class.static.data]中公开提供的最接近C ++ 03的标准草案说:

如果静态数据成员是const integer或const枚举类型,则它在类定义中的声明可以指定一个常量初始化器,它应该是一个整型常量表达式(5.19)。 在这种情况下,成员可以出现在整数常量表达式中。 如果在程序中使用该成员,并且名称空间范围定义不包含初始化程序,则该成员仍应在名称空间作用域中定义。

和草案C ++ 11标准第9.4.2[class.static.data]说:

如果非易失性const静态数据成员是整数类型或枚举类型,则其在类定义中的声明可以指定一个大括号或大小为初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式(5.19) 。 可以使用constexpr说明符在类定义中声明文字类型的静态数据成员; 如果是这样,它的声明应指定一个大括号或等于初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式。 [...]

这在C ++ 14标准草案中几乎相同。

类内静态const“定义”实际上是声明。 当定义一个变量时,编译器会为该变量分配内存,但这不是这里的情况,即获取这些静态const-in-class内容的地址是错误的,NDR。

这些东西应该被用在代码中,但是浮点类型并不容易,因此不允许这样做。

通过在类外定义静态const变量,您向编译器发出信号,告知这是真正的定义 - 具有内存位置的真实实例。

暂无
暂无

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

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