C++整数常量表达式定义
C++ integral constant expression definition
在当前的C++标准中,有以下段落(expr.const#5)(强调我的):
整型常量表达式是整型或无作用域枚举类型的表达式,隐式转换为 prvalue,其中转换后的表达式是核心常量表达式。[注意:此类表达式可用作位字段长度,如果基础类型不固定,则用作枚举器初始值设定项([dcl.enum]),以及用作对齐方式。
关于这个定义,我有两个问题:
短语"隐式转换为prvalue"是否意味着要使表达式被视为"整数常量表达式",它必须出现在强制其隐式转换为 prvalue 的上下文中?
"转换后的表达式"指的是什么?我知道这个问题在转换后的常量表达式定义的澄清中得到了解决。那里给出的答案是,在以下初始化之后,"转换后的表达式"是
t
:T t = expr;
。但是,我看不出计算该表达式(t
)如何与[expr.const#4](描述表达式被视为核心常量表达式所需条件的段落)中给出的任何规则相匹配,这将使它不合格为核心常量表达式。
谢谢。
整型常量表达式隐式转换为 prvalue 的语句意味着左值到右值的转换应用于用作整型常量表达式的任何表达式。 在表达式可能是整型常量表达式(初始化可能在常量表达式中使用的常量限定整数类型的非本地对象)的一种情况下,初始值设定项无论如何都是 prvalue,因此不会发生解释更改。
除此之外,您的两个问题都有相同的答案:将表达式(如所写的)转换为 prvalue 整数类型所需的任何转换也必须允许在核心常量表达式中(例如,请参阅引用之前的/4.7 和它之后的/6)。 "转换表达式"包括T t=e;
解释中的转换,而不仅仅是id-expressiont
(例如,它始终是一个左值)。
我查看了 clang 的源代码,特别是 "SemaOverload.cpp" 中的函数 "CheckConvertedConstantExpression"。在那里执行的操作如下:
- 查找所需的隐式转换序列
- 检查是否仅使用 http://eel.is/c++draft/expr.const#7 中列出的转化
- 执行隐式转换(在此步骤中,我相信会创建一个新表达式,例如,如果原始表达式
f()
具有用户定义的 int 转换函数的类类型A
,并且上下文需要int
,那么新表达式应该f().operator int()
) - 检查是否需要任何缩小范围转换
- 计算在步骤 3 生成的表达式(隐式检查它是否为
constant expression
)
因此,我相信,正如@Davis Herring的回答中所述,术语"转换表达式"是指一个新表达式,其评估包括对程序中编写的原始表达式的评估,以及对任何所需转换的评估。
- 带有用户定义类的c++折叠表达式
- 定义有趣的宏和正则表达式在Z3 C++绑定
- Tbb 库:错误:编写自定义类函数而不是 lambda 表达式时,对函数的调用不匹配
- 使用表达式 SFINAE 的函数模板的类外定义
- 标准库中的任何正则表达式语法是否支持 (?(定义)用于子模式参考?
- 表达式必须具有常数值,变量不能用作定义数组大小的常数
- 表达式模板玩具示例:用户定义的强制转换不适用于复杂类型
- 我们可以重新定义正则表达式吗
- 需要支持定义正确的正则表达式
- 这种关系不等于定义良好的表达式吗?
- 在C++中,当表达式涉及对象时,将表达式赋值到对象中时,是否有定义的操作顺序?
- 在 C 和 C++ 中,使用逗号运算符的表达式是否未定义"a = b, ++a;"?
- 是否可以定义以后可以计算的布尔表达式
- 将编译时定义大小的数组初始化为常量表达式
- C++整数常量表达式定义
- 在语法树中的节点上定义的层次结构的表达式模板
- 如何查找除使用正则表达式定义的句子之外的所有句子
- 使用自定义表达式类提升精神表达式解析器
- 释放用户定义表达式析构函数中的动态内存
- 用数学方法定义表达式的结果