隐式转换和运算符重载

Implicit conversion and operator overload

所以,我写了这样的东西

#include <iostream>
using namespace std;

void f(int32_t i)
{
    cout << "int32: " << i << endl;
}

void f(int16_t i)
{
    cout << "int16: " << i << endl;
}

void f(int8_t i)
{
    cout << "int8: " << i << endl;
}

void f(uint32_t i)
{
    cout << "uint32: " << i << endl;
}

void f(uint16_t i)
{
    cout << "uint16: " << i << endl;
}


int main() {
    uint8_t i = 0u;
    f(i);
    return 0;
}

它打印了

int32: 0

我有点懵:

在比较不同重载函数所需的转换时,"promotion" 被认为是比标准 "conversion" 更好的转换序列。每种算术类型最多可以提升为一种其他类型。 (在将参数传递给 printf 等 C 风格的可变参数函数时也会使用提升。一元运算符 + 可用于强制提升算术表达式,如 +n。 )

对于不是字符类型或 bool 的整数类型,提升的类型是:

  • 如果int可以表示原类型的所有值,那么int;
  • 否则,如果unsigned int可以表示原始类型的所有值,则unsigned int
  • 否则,原始类型本身(推广没有任何作用)

在您的示例中,比较重载函数时,"exact match" 最好,但没有函数完全采用 int8_t(或 int8_t&const int8_t& ). uint8_t 的提升类型是 int,因为它需要支持比 0-255 大得多的范围。显然在您的系统上,int32_tint 的别名,因此函数 void f(int32_t); 只需要对参数进行提升。其他函数都是可行的,但需要对参数进行整数转换。所以void f(int32_t);被认为是最好的重载。

所以这个问题的技术答案是它是特定于实现的,但只是因为 int<cstdint> 类型之间的关系,而不是因为重载解析规则。

行为定义明确,特定于实现。使用 16 位 int 会有所不同。

标准中的具体规则是:

[over.best.ics] 用于重载解析。 [conv.prom]积分促销。