静态类成员的常量表达式初始值为double类型 [英] Constant expression initializer for static class member of type double
问题描述
在C ++ 11和C ++ 14中,为什么我需要 constexpr
:
In C++11 and C++14, why do I need constexpr
in the following snippet:
class Foo {
static constexpr double X = 0.75;
};
,但这会产生编译器错误:
whereas this one produces a compiler error:
class Foo {
static const double X = 0.75;
};
(更奇怪的是)这个编译没有错误?
and (more surprisingly) this compiles without errors?
class Foo {
static const double X;
};
const double Foo::X = 0.75;
推荐答案
在C ++ 03中,在枚举类型的const积分的静态成员变量的类初始化器中,在C ++ 11中,我们可以使用constexpr初始化类中的文字类型的静态成员。这个限制保留在C ++ 11中的const变量主要是为了兼容性,C ++ 03我们可以从 closed issue 1826:常量表达式中的const浮点数,它说:
In C++03 we were only allowed to provide an in class initializer for static member variables of const integral of enumeration types, in C++11 we could initialize a static member of literal type in class using constexpr. This restriction was kept in C++11 for const variables mainly for compatibility will C++03 we can see this from closed issue 1826: const floating-point in constant expressions which says:
用常数初始化的const整数可以在常量表达式中使用,但是用常量初始化的const浮点变量不能。这是故意的,与C ++ 03兼容,同时鼓励一致使用constexpr。然而,有些人发现这种区别是令人惊讶的。
A const integer initialized with a constant can be used in constant expressions, but a const floating point variable initialized with a constant cannot. This was intentional, to be compatible with C++03 while encouraging the consistent use of constexpr. Some people have found this distinction to be surprising, however.
CWG最后将此请求关闭为不是缺陷),基本上说:
CWG ended up closing this request as not a defect(NAD), basically saying:
程序员希望浮点值参与常量表达式应使用constexpr而不是const。 / p>
that programmers desiring floating point values to participate in constant expressions should use constexpr instead of const.
参考 N1804
9.4.2 [class.static.data] 说:
如果静态数据成员是const整数或const枚举类型,它在类定义中的声明可以
指定一个常量初始化器,它应该是一个整数常量表达式(5.19)。在这种情况下,成员可以在整型常数表达式中出现
。如果在程序中使用,则成员仍然在命名空间范围中定义,并且
命名空间范围定义不包含初始化程序。
If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.
和草稿C ++ 11标准部分 9.4.2
[class.static.data] 说:
and the draft C++11 standard section 9.4.2
[class.static.data] says:
如果非易失性const静态数据成员是积分或枚举类型,它在
类定义中的声明可以指定一个大括号 - 等式初始化器,其中作为赋值表达式
的每个initializer子句都是常量表达式(5.19)。可以在
类定义中使用constexpr说明符声明文字类型的静态数据成员;如果是,其声明应指定一个括号或初始值为
,其中作为赋值表达式的每个initializer子句都是一个常量表达式。 [...]
If a non-volatile 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.19). 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. [...]
这在草案C ++ 14标准中是相同的。
this is pretty much the same in the draft C++14 standard.
这篇关于静态类成员的常量表达式初始值为double类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!