非常量对象的constexpr引用

5

声明一个非const引用作为constexpr,是否允许?示例代码:

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

这个代码在gcc和clang上是可以通过的(我在当前和过去几个版本中尝试过,直到C++11),但我认为它不应该被接受,因为C++14的[dcl.constexpr/9]规定如下:
如果在引用声明中使用constexpr说明符,则出现在其初始化器中的每个完整表达式都应该是常量表达式。
而x不是常量表达式。
最新的C++17草案中[dcl.constexpr]的语言已经改变,甚至不再明确提及constexpr参考了,我无法理解它对它们想要表达什么。

1
谁说 x 不是一个常量表达式? - T.C.
x不是核心常量表达式” {{需要引用}} - T.C.
x 被赋予了一个字面值,这难道不足以让编译器知道它是编译时已知的吗? - asimes
评估表达式 x 如何需要对其进行 lvalue-to-rvalue 转换? - T.C.
@T.C. 我以为这是暗示的,但显然不是。所以 x 将被 /2.9 覆盖,我假设它的意思是说,如果 id-expression 表示一个对象,并且该对象使用常量表达式初始化,则该对象是常量表达式。对我来说不清楚这句话是指“(变量)或(引用类型的数据成员)”还是“(变量或数据成员)的引用类型”。 - M.M
显示剩余2条评论
1个回答

4
假设 x 具有静态存储期,左值表达式 x 是一个完全有效的常量表达式。
如果您在需要 prvalue 的上下文中使用 x,这将导致应用 lvalue-to-rvalue 转换到它上面,那么所得到的 prvalue 表达式 - 称为 TO_RVALUE(x) - 将不是常量表达式,这是显而易见的。但是在引用绑定的情况下,不存在这样的转换。

这取决于初始化器吗?(例如,int x = rand(); 仍然会使 x 成为常量表达式吗?) - M.M
@M.M No. (Yes.) 左值常量表达式只是指定实体(基本上就像其地址一样)。它被初始化的内容无关紧要,甚至不需要为编译器所知(例如,extern int x;就足够了)。 - T.C.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接