GCC要求此引用声明使用constexpr说明符是否正确
Is GCC correct in requiring the constexpr specifier for this reference declaration?
下面的代码没有在GCC 5.3.0下编译,因为r
的声明缺少constexpr
说明符。
const int i = 1;
const int& r = i;
constexpr int j = r;
我相信拒绝是正确的。如何使用工作草案N4527来证明它?
首先,由于我们使用的是引用,因此不能违反[expr.const]/(2.9)。(2.9.1)适用,不过:
引用的变量或数据成员的id表达式引用类型,除非该引用具有先前的初始化,并且
-使用常量表达式初始化
也就是说,只要初始化器i
-是一个常量表达式(如下所示),使用r
就可以了
还需要检查第3行中的l-t-r转换是否合法,即不得违反(2.7)。但是,(2.7.1)适用:
左值到右值的转换(4.1),除非它应用于
--a引用的整数或枚举类型的非易失性glvalue一个完整的非易失性const
对象初始化,用常量表达式或初始化
…这也很好,因为(g)左值是r
,它指的是i
-这是一个非易失性const
对象,具有常量表达式初始值设定项(1
)。
我们推迟了证明i
实际上是一个常数表达式的时间,一旦解决了这个问题,我们就需要证明r
是一个常量表达式
[expr.const]/5与此相关:
常量表达式是glvalue核心常量表达式其值指的是一个实体,该实体是常量表达式(定义如下),或prvalue核心常量其值为对象的表达式,其中,对于该对象及其子对象:
- 引用类型的每个非静态数据成员都引用了一个实体,该实体是常量表达式的允许结果,并且
- 如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址,即过去的地址此类对象(5.7)的结尾、函数的地址或null指针值
如果实体是静态存储持续时间为要么不是临时对象,要么是值满足上述约束的临时对象,或者是作用
由于i
在上面的上下文中是一个(g)左值,它必须是常量表达式的允许结果——事实就是这样,因为它有静态存储持续时间,当然不是临时的。因此CCD_ 13是一个常数表达式。
然而,r
在第3行中被视为一个prvalue。由于我们已经确定r
是一个核心常量表达式,因此我们只需要检查要点。不过,他们显然相遇了。
因此,代码在命名空间范围内是格式良好的。它将不在局部范围内,因为i
将不再是常量表达式的允许结果。Clang给出了一个全面的错误信息。
- 激励'inline'说明符的真实世界示例?
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 多成员Constexpr结构初始化
- 条件constexpr函数
- 缺少类型说明符,显式类型为"缺少错误"
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- Visual C++ constexpr Hints
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 为什么constexpr的性能比正常表达式差
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 为什么std::isnan 不是 constexpr?
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 更多constexpr容器是否需要mark_immutable_if_consexpr
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- constexpr上下文中std::initializer_list的验证
- 在类外部初始化的 constexpr 静态成员的声明中是否需要 constexpr 说明符
- VC++编译器升级2010->2015重新定义; 'constexpr'说明符不匹配
- GCC要求此引用声明使用constexpr说明符是否正确