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



对于以下表达式:-

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 + float时,unsigned被转换成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,编译失败。

相关内容

  • 没有找到相关文章

最新更新