const int i = 1; const int& r = i; constexpr int j = r;
我相信拒绝是正确的.如何使用N4527工作草案证明这一点?
解决方法
an id-expression that refers to a variable or data member of
reference type unless the reference has a preceding initialization and
either
— it is initialized with a constant expression
即使用r很好,只要初始化器 – i – 是一个常量表达式(如下所示).
还必须检查第3行中的l-t-r转换是否合法,即不得违反(2.7).但是,(2.7.1)适用:
an lvalue-to-rvalue conversion (4.1) unless it is applied to
— a
non-volatile glvalue of integral or enumeration type that refers to
a complete non-volatileconst
object with a preceding
initialization,initialized with a constant expression,or
……所以这很好,因为(g)左值是r,它指的是i – 这是一个带有常量表达式初始化器(1)的非易失性const对象.
我们推迟显示我实际上是一个常量表达式,一旦这样,我们需要证明r是一个常量表达式.
[expr.const] / 5与此有关:
A constant expression is either a glvalue core constant expression
whose value refers to an entity that is a permitted result of a
constant expression (as defined below),or a prvalue core constant
expression whose value is an object where,for that object and its
subobjects:
- each non-static data member of reference type refers to an entity that is a permitted result of a constant expression,and
- if the object or subobject is of pointer type,it contains the address of an object with static storage duration,the address past
the end of such an object (5.7),the address of a function,or a null
pointer value.An entity is a permitted result of a constant expression if it is an object with static storage duration that is
either not a temporary object or is a temporary object whose value satisfies the above constraints,or it is a
function.
因为在上面的上下文中,我是(g)左值,它必须是常量表达式的允许结果 – 因为它具有静态存储持续时间并且当然不是临时的.因此,我是一个不变的表达.
然而,r被视为第3行中的prvalue.由于我们已经确定r是核心常数表达式,我们只需要检查项目符号.不过,他们显然已经相遇了.
因此,代码在命名空间范围内格式良好.它不会在本地范围内,因为我不再是常量表达式的允许结果. Clang gives a comprehensive error message.