2017-04-21 77 views
4

允许声明一个非const引用为constexpr?示例代码:constexpr对非const对象的引用

int x = 1; 
constexpr int& r = x; 

这是通过gcc和铛接受(我试图两者的几个当前和过去的版本,回到C++ 11,和所有接受了它)。然而,我认为它不应该被接受,因为C++ 14 [dcl.constexpr/9]表示:

如果constexpr说明符以引用声明使用

,则出现在其初始值设定每全 表达应是一个常量表达式

x不是一个常量表达式。

[dcl.constexpr]的最新C++ 17草案中的语言发生了变化,甚至没有提及明确引用constexpr,我无法对它们进行说明。

+1

谁说'x'不是一个常量表达式? –

+0

“'x'不是核心常量表达式”{{引用需要}} –

+0

@ T.C。 [expr.const]/2“e”是一个核心常量表达式,除非[e]的评估会评估以下值之一:左值到右值的转换,除非它适用于[例子这个代码不匹配]“ –

回答

4

假设x具有静态存储持续时间,左值表达式x是一个完全有效的常量表达式。

如果在需要prvalue,这导致左值到右值转换为被施加到其上的上下文中使用x,然后将所得prvalue表达 - 称之为TO_RVALUE(x) - 将不是一个常量表达式,由于明显的原因。但在引用绑定的情况下,不存在这种转换。

+0

它依赖于初始化器吗? (例如'int x = rand();'仍然使'x'成为一个常量表达式?) –

+0

@ M.M否(是)一个左值常量表达式仅仅指定实体(基本上,就像它的地址)。它的初始化是无关紧要的,编译器甚至不需要知道它(例如'extern int x;'就足够了)。 –