从其他QUESTION他们谈到Bjarne Stroustrup如何表示,正如将int
(例如short
)更窄的整数数据类型提升为int
,float
被提升为double
。但是,与扩展比int
更窄的积分不同, 浮点促销 不会以相同的方式发生,而是发生在其他地方。
我知道如果你要计算float + double
,float
会在应用二元运算符(double
)之前转换为+
。但是,根据Learncpp.com,这不是 浮点促销 。这是 通常的算术转换 。
浮点数促销何时实际发生?
答案 0 :(得分:13)
有这样的事情"浮点促销"每[conv.fpprom] float
到double
。
类型
float
的prvalue可以转换为double
类型的prvalue。价值没有变化。此转换称为浮点促销。
链接问题的答案是正确的。添加两个float
时,不应自动进行此促销,因为通常的算术转换不会提升浮点操作数。
将float
作为操作数传递给省略号时会发生 ,就像在printf
中一样。这就是%f
格式说明符打印float
或double
的原因:如果您传递float
,该函数实际上会收到double
,促销的结果。
浮点升级的存在对于重载决策也很重要,因为积分促销和浮点促销具有比积分转换更好的隐式转换排名< / em>,浮点转换和浮动积分转换。
示例1:
void f(double);
void f(long double);
f(0.0f);
这会调用void f(double)
,因为促销double
优于转化为long double
。相比之下,请考虑这个可能令人惊讶的例子2:
void f(long double);
void f(int);
f(0.0f);
这是含糊不清的。从float
到long double
的转换并不比从float
到int
的转换更好,因为它们都不是促销。
示例3:
struct S {
operator float();
operator int();
};
double d = S();
这会调用operator float
,然后将生成的float
值提升为double
,以初始化d
。
答案 1 :(得分:6)
应用浮点促销的主要(可能唯一)时间是将参数传递给可变参数函数(例如printf
)。
在这种情况下,通常的算术转换不适用(它们用于在表达式中的两个操作数之间查找公共类型)。
该标准的相关部分是[expr.call] / 7(至少从N4296开始):
当给定参数没有参数时,参数的传递方式使得接收函数可以通过调用va_arg(18.10)来获取参数的值。
[...]
如果参数具有由积分促销(4.5)或浮点促销(4.6)限制的浮点类型的积分或枚举类型,则参数的值将在调用之前转换为提升类型