C++为什么我可以在类定义中初始化静态const char而不是静态const double?

use*_*501 13 c++ static-members constexpr c++11

这是两行代码:

static const double RYDBERG_CONST_EV = 13.6056953;
static const char CHAR_H_EDGE = '-';
Run Code Online (Sandbox Code Playgroud)

第二行编译没有错误,第一行不编译.(错误:'constexpr' needed for in-class initialization of static data member...)

解决方案显然是constexpr在类型之前添加关键字.这是必需的,因为double它不是"整体类型".但为什么整数和浮点类型之间的行为不同?

5go*_*der 14

我不相信这是有充分理由的,除非它在历史上有所增长.

在C++ 11之前,积分类型的例外是可取的,因为人们希望将它们用作数组大小.这与整体const蚂蚁被视为常量表达式的另一个例外相关.浮点类型不存在的异常.

const int    ni = 10;
const float  nf = 10.0f;
int numbers1[(unsigned) ni];  // perfectly fine in all versions of C++
int numbers2[(unsigned) nf];  // error in all versions of C++
Run Code Online (Sandbox Code Playgroud)

当C++ 11引入时constexpr,它可以做任何事情,const整体类型的特殊外壳可以做更多.对于任何文字类型,它的工作方式相同.因此,给定一个优秀的工具,不需要将整数类型的现有规则扩展到浮点.

今天,整体类型的特殊外壳大多是早期较暗日的遗留物.它无法从语言中删除,因为这样做会破坏依赖于这种特殊外壳的现有代码,但是通过添加更多的异常,使得语言变得更加复杂,因为今天完全不需要这些异常constexpr.人们应该被期望迁移到constexpr并且不再担心旧的残余.我认为这是一个非常合理的决定,但你当然可以争辩说应该做出另一个决定.

附录

正如TC所评论的那样,有一个关于这个问题的(非)缺陷报告,委员会确认行为不会改变,人们应该开始使用constexpr.

1826. const常量表达式中的浮点数

条:5.20 [expr.const]状态:NAD发布者:Ville Voutilainen日期:2014-01-04

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

还观察到允许const浮点变量作为常量表达式将是ABI突破性变化,因为它会影响λ捕获.

一种可能性可能是const在常量表达式中不推荐使用积分变量.

附加说明,2015年4月:

EWG要求CWG允许const在常量表达式中使用浮点变量.

理由(2015年5月):

CWG认为当前的规则不应该改变,并且希望浮点值参与常量表达式的程序员应该使用constexpr而不是const.