在C ++ 11标准(N3690)的最新草案中有11个对core constant expression
表达式的引用,它们都没有定义这个实体是什么。
我们也可以发现表达式core constant expression
定义得非常明确here,基本上与标准用于定义表达式conditional-expression
的术语相同。
因此,我想在这个问题上得到一些意见,在我看来,标准中是错误的。
现在,假设cppreference中的定义是正确的,我还想知道为什么以下代码段在Coliru和Ideone中编译,尽管在提到的定义中有第(10)项?
#include <iostream>
int main()
{
const double x = 2.;
constexpr double y = x;
std::cout << y << std::endl;
}
我特别考虑表达式lvalue to rvalue implicit conversion
中变量x
的{{1}},其中没有任何条款(a),(b)和(c)在上文提到的第(10)项中。
感谢您的帮助。
答案 0 :(得分:5)
N3690 确定在5.19p2 [expr.const]中定义“核心常量表达式”:
条件表达式 e 是核心常量表达式,除非 评估 e ,遵循抽象机的规则(1.9), 将评估以下表达式之一:
[list ignored]
已发布的ISO C ++ 2011标准在同一部分中对其进行了定义。
至于这是否真的是一个定义,另见第1.3节第3段:
仅在本国际的一小部分内使用的条款 标准是在使用它们的地方定义的,并且在它们所在的位置使用斜体 定义
该标准还使用斜体来表示句法类别,例如条件表达式,但“核心常量表达式”是一个定义的术语,而不是句法类别(它是微妙的,但你可以通过使用来判断空格而不是连字符来分隔单词。)
示例代码:
const double x = 2.;
constexpr double y = x;
我对该标准的解读是这是无效的,因为x
不 核心常量表达式。如果x
和y
具有某种整数或枚举类型,那么它是有效的,但是没有浮点数的这种权限。 核心常量表达式中不允许进行左值到右值的转换(将对象的名称x
转换为其值2.0
),除非它符合列出的三个之一标准(见C11 5.19,第9个子弹,3个子弹)。
这意味着在没有诊断的情况下接受上述代码的编译器是不符合的(即,错误)。 (除非我遗漏了一些东西,这完全有可能。)
这意味着http://en.cppreference.com/w/cpp/language/constant_expression是错误的。它表示核心常量表达式可能包含左值的左值到右值的转换,“左值”具有文字类型并且引用用常量表达式(或其子对象)定义的对象“。实际标准有更强的要求:必须使用constexpr
定义对象。 (也许cppreference.com是基于早期的草案?)
因此,通过将示例代码更改为:
,可以使示例代码有效constexpr double x = 2.;
constexpr double y = x;