繁体   English   中英

c++ 在表达式中查找隐式类型转换

[英]c++ find implicit type conversion in the expression

对于以下表达式:-

int main()
{
    unsigned ui = 1;
    float fval = 2.5;
    cout << sizeof(ui) << endl << sizeof(fval) << endl;
    cout << typeid(ui+fval).name();
}

我们得到以下输出:-

4
4
f

似乎 ui+fval 是一个浮点数。

但是,鉴于 float 和 unsigned int 都是 4 个字节,并且并非所有 unsigned int 值都可以放入一个 float 中,那么 fval 不应该转换为 unsigned int 吗?

算术运算符的规则实际上与一般函数重载解析的规则略有不同。

算术运算符的cppreference :

转化次数

如果传递给算术运算符的操作数是整数或无作用域枚举类型,则在任何其他操作之前(但在左值到右值转换之后,如果适用),操作数会进行整数提升。 如果操作数具有数组或函数类型,则应用数组到指针和函数到指针的转换。

对于二元运算符(移位除外),如果提升的操作数具有不同的类型,则应用额外的一组隐式转换,称为通常的算术转换,其目标是生成公共类型(也可通过std::common_type类型特征访问) . 如果在任何整数提升之前,一个操作数是枚举类型而另一个操作数是浮点类型或不同的枚举类型,则不推荐使用此行为。 (C++20 起)

  • 如果任一操作数具有范围枚举类型,则不执行转换:另一个操作数和返回类型必须具有相同的类型
  • 否则,如果任一操作数是long double ,则另一个操作数将转换为long double
  • 否则,如果任一操作数为double ,则另一个操作数将转换为double
  • 否则,如果任一操作数为float ,则另一个操作数将转换为float

[剪辑]

所以,很明显,当我们在做unsigned + floatunsigned被转换为float 这是适用的第一条规则,因此我们遵循它。

但是,对于一般重载解析,从unsignedfloat的转换等效于从floatunsigned的转换。 因此,例如在以下代码片段中:

unsigned add(unsigned l, unsigned r) { return l + r;  }
float add(float l, float r) { return l + r;  }

int main()
{
    unsigned ui = 1;
    float fval = 2.5;
    add(ui, fval);
}

它无法决定使用哪个版本的add并且无法编译。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM