我读过这个
整数提升:小整数类型(例如 char)的纯右值可以转换为较大整数类型(例如 int)的纯右值。- 第一行
[...详细信息 - 不重要...]
请注意,所有其他转化都不是促销;例如,重载决策选择 char -> int (提升)而不是 char -> Short (转换)。- 最后一行。
从 char -> int 的转换是 'promotion' ;很明显(从 1 个字节到 4 个字节)
从 char -> Short 的转换是“不升级”;为什么?
我一直认为char是一个字节,short(short int)是两个字节。为什么它不被视为促销?这似乎与第一行相矛盾 - 这不是意味着“从小类型转换为大类型”是升级吗?)
-----编辑:在寻找一些答案后:
我们可以考虑“促销是转换的特殊情况”吗?,我们是否可以说“所有促销都是转化,但并非所有转化都是促销”?
或者我们应该将它们视为两个不同且独立的概念?
历史动机:C
积分提升的思想可以追溯到标准之前的 C。当向可变参数函数 (
...
) 或没有原型的函数提供参数时,就会应用提升。即调用:促销基本上是对该类型的“最小”升级,而转换可以是任何内容。您甚至可以认为该设计是基于 B 编程语言构建的结果,该语言甚至没有像 C 那样具有多种整数类型。
C++标准中的相关措辞
标准C++中的相关段落是:
- [转换舞会] p2
促销和转化之间的区别解释如下:
- [转换积分] p4
正如您所看到的,这两个概念之间存在一些重叠,但任何同时也是促销的转换都不被视为转换。
对过载解决的影响
正如您所指出的,
char -> short
是转换,char -> int
是晋升。在某些情况下,这会对重载解析产生重大影响:如果现在 C++ 是从头开始设计的,那么升级和转换的定义可能会有很大不同,但是,现状就是我们所拥有的,而且不太可能改变。经过这么多年,改变这种行为和措辞基本上是不可能的,因为有多少代码依赖于它。
与 C++ 中的许多设计决策一样,答案是:历史原因。
to
char
和toint
都是转换。请注意在讨论促销后文本使用“所有其他转化”:促销是转化的一种类型。char
short
转换是一种操作,它采用一种形式的值并以另一种形式产生相同的值(尽可能接近):
char
值并生成int
具有相同值的值是一种转换。int
值并生成一个包含表示相同值的十进制数字的字符串是一种转换。在表达式的许多地方,C++ 自动将窄整数类型转换为更宽的整数类型。这样做主要是出于历史目的,而且还因为纯粹以狭窄类型进行算术可能会很尴尬 -
char
算术很容易溢出,并且要求程序员显式插入强制转换int
会使代码变得麻烦。这些特殊的转换称为“促销”。该词的自然英语含义,前进到更高的位置,适合这些类型的转换:它们都从较窄的类型转换为较宽的类型(或至少转换为更宽的类型)。除此之外,这个词被用来专门指代这些特殊的转换。积分促销的一个重要特点是其价值永远不会改变。(理想情况下,任何转换都不会改变值,但由于限制,这种情况确实会发生。一个例子是,将值
float
3¼ 转换为int
必须生成一个整数,因此生成 3 而不是 3¼。另一个例子是,将int
值转换为 -3到unsigned
力环绕,因此会产生名义上非常不同的值,尽管它确实与输入值有特殊关系并且在模算术中可以被视为相同的值。)C++ 标准指定了一组整数提升规则,这些规则不仅仅基于类型的大小。
char
将 a 升级为 anint
而不是 a的决定short
基于该语言的历史设计以及跨不同平台一致行为的愿望。根据 C++ 标准,定义整型提升以将小整型类型转换为特定的实现定义类型,通常是
int
. 由于int
选择 为积分提升的目标类型,因此将 a 转换char
为 ashort
并不符合提升资格,即使short
大于char
。相反,它属于转换类别。不同的实现和架构之间的具体规则可能有所不同,但这是您观察到的行为背后的一般推理。它是语言设计的一部分,以历史考虑和编译器实现的实际方面为指导,而不是基于类型大小的严格逻辑进展。
简短的回答(对不起,双关语)就是它的定义方式。
显然,从 char(1 个字节)到 Short(2 个字节)应该是“安全”转换(因此是“升级”?)。然而,引用的部分具体说明了哪些转化被归类为“促销”,但没有简短说明。就是这样。为什么?不确定 - 文本确实说算术运算符不接受小于 int 的操作数,因此“提升”为 Short 可能没有意义,因为它只需要在稍后的时间提升为 int 。