隐式转换和运算符重载

时间:2019-03-02 12:32:29

标签: c++ c++11 overloading implicit-conversion

所以,我写了这样的东西

#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

我有点困惑:

  • 这是定义良好的行为,还是特定于实现的?

  • 哪些规则可以确定此处使用哪种重载以及将变量转换为哪种类型?

2 个答案:

答案 0 :(得分:22)

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

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

  • 如果int可以代表原始类型的所有值,则int;
  • 否则,如果unsigned int可以代表原始类型的所有值,则unsigned int;
  • 否则,原始类型本身(促销不起作用)

在您的示例中,比较重载函数时,“完全匹配”将是最佳选择,但没有函数采用正好int8_t(或int8_t&const int8_t&)的形式。 uint8_t的提升类型为int,因为它需要支持远大于0-255的范围。显然,在您的系统上,int32_tint的别名,因此函数void f(int32_t);仅需要对参数进行升迁。其他函数都是可行的,但需要对参数进行整数转换。因此,void f(int32_t);被认为是最佳的重载。

因此,对该问题的技术解答是,它是特定于实现的,但这仅是由于int<cstdint>类型之间的关系,而不是由于过载解析规则。

答案 1 :(得分:9)

该行为是定义明确的,但是特定于实现的。如果使用16位的int,那就不一样了。

标准中的特定规则为:

[over.best.ics]用于解决过载。 [conv.prom]进行整体促销。