为什么我们需要两个定义:整型常量表达式和转换常量表达式?

2024-02-22

C++14 中的§5.19/3 定义了整型常量表达式和转换常量表达式:

An 积分常量表达式是积分或的表达式 无范围枚举类型,隐式转换为纯右值,其中 转换后的表达式是核心常量表达式。 [ 注:此类 表达式可以用作数组边界(8.3.4、5.3.4)、位字段 长度 (9.6),作为枚举器初始值设定项(如果基础类型是) 不固定(7.2),并且作为对齐(7.6.2)。 ——尾注] A转换的 常量表达式类型的T是一个隐含的表达式 转换为类型的纯右值T,其中转换后的表达式是 核心常量表达式和隐式转换序列 仅包含用户定义的转换、左值到右值的转换 (4.1)、积分促销 (4.5) 和积分兑换 (4.7) 其他 比缩小转换(8.5.4)。 [注:这样的表达方式可能是 用于new表达式(5.3.4),如case表达式 (6.4.2),如 如果基础类型是固定的(7.2),则枚举器初始值设定项如下 数组边界 (8.3.4),以及作为整数或枚举非类型模板 论据(14.3)。 ——尾注]

也许我错过了一些东西,但我的第一印象是每个积分常量表达式 is a 转换后的常量表达式.

Edit

而且我也认为这一段有一个错误:

代替:

A converted constant expression of type T is an expression, implicitly converted to a prvalue of type T, ...

它应该是:

A converted constant expression of type T is an expression, implicitly converted to a prvalue of an integral type, ...

此更改允许编译以下代码:

#include <iostream>
struct A { operator int() { return 5; } } a;

int main() {
    int b[a]{ 0, 1, 2, 3, 4 };
    std::cout << b[4] << '\n';
}

where a在声明中int b[a]{ 0, 1, 2, 3, 4}; is a 转换后的常量表达式类型的A,隐式转换为整数类型的纯右值 (int) 其中转换后的表达式5 is a 核心常量表达式,并且隐式转换序列仅包含用户定义的转换。


两种定义都是必需的,因为有些事情可以用其中一种定义来完成,但用另一种定义则不行。不,不是每个积分常量表达式确实是一个转换后的常量表达式。对于一个明显的例子,转换后的常量表达式禁止缩小转换范围,但积分常量表达式没有。

因此我不能这样做:

enum x : char { a = 1024 };

但是,如果枚举的初始值设定项允许积分常量表达式,而不是一个转换后的常量表达式,正是允许的。

作为维恩图,我将这种情况画成这样:

因此,两者之间有相当多的重叠(可能比该图暗示的更多),但每个都允许至少一些另一个不允许的事情。我已经在每个方向上给出了一个项目的示例,但没有尝试详尽地列出差异。

不过,我并不完全相信整型常量表达式禁止用户定义的转换(快速测试表明我目前手头的编译器允许它们)。这将给出我最初写这个答案的情况,这更像是这样:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我们需要两个定义:整型常量表达式和转换常量表达式? 的相关文章

  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 如何从 C# 中的 dataTable.Select( ) 查询中删除单引号?

    所以我有一个经销商名称列表 我正在我的数据表中搜索它们 问题是 一些傻瓜必须被命名为 Young s 这会导致错误 drs dtDealers Select DealerName dealerName 所以我尝试替换字符串 尽管它对我不起作
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • 以编程方式读取 SQL Server 查询计划建议的 SQL 特定执行的索引?

    如果我在 SSMS 中运行此命令 set showplan xml on GO exec some procedure arg1 arg2 arg3 GO set showplan xml off GO 我获得查询执行中涉及的完整调用堆栈的
  • 如何判断计算机是否已重新启动?

    我曾经使用过一个命令行 SMTP 邮件程序 作为试用版的限制 它允许您在每个 Windows 会话中最多接收 10 封电子邮件 如果您重新启动计算机 您可能还会收到 10 个以上 我认为这种共享软件破坏非常巧妙 我想在我的应用程序中复制它
  • Python 属性和 Swig

    我正在尝试使用 swig 为一些 C 代码创建 python 绑定 我似乎遇到了一个问题 试图从我拥有的一些访问器函数创建 python 属性 方法如下 class Player public void entity Entity enti
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动
  • 如何在 Qt 应用程序中通过终端命令运行分离的应用程序?

    我想使用命令 cd opencv opencv 3 0 0 alpha samples cpp cpp example facedetect lena jpg 在 Qt 应用程序中按钮的 clicked 方法上运行 OpenCV 示例代码
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 检测到严重错误 c0000374 - C++ dll 将已分配内存的指针返回到 C#

    我有一个 c dll 它为我的主 c 应用程序提供一些功能 在这里 我尝试读取一个文件 将其加载到内存 然后返回一些信息 例如加载数据的指针和内存块的计数到 c Dll 成功将文件读取到内存 但在返回主应用程序时 程序由于堆损坏而崩溃 检测
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 打印大型 WPF 用户控件

    我有一个巨大的数据 我想使用 WPF 打印 我发现WPF提供了一个PrintDialog PrintVisual用于打印派生的任何 WPF 控件的方法Visual class PrintVisual只会打印一页 因此我需要缩放控件以适合页面
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • 这个可变参数模板示例有什么问题?

    基类是 include
  • 如何在richtextbox中使用多颜色[重复]

    这个问题在这里已经有答案了 我使用 C windows 窗体 并且有 richtextbox 我想将一些文本设置为红色 一些设置为绿色 一些设置为黑色 怎么办呢 附图片 System Windows Forms RichTextBox有一个
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • 不区分大小写的字符串比较 C++ [重复]

    这个问题在这里已经有答案了 我知道有一些方法可以进行忽略大小写的比较 其中涉及遍历字符串或一个good one https stackoverflow com questions 11635 case insensitive string
  • OpenCV SIFT 描述符关键点半径

    我正在深入研究OpenCV的SIFT描述符提取的实现 https github com Itseez opencv blob master modules nonfree src sift cpp 我发现了一些令人费解的代码来获取兴趣点邻域

随机推荐