【问题标题】:Implicit conversion and operator overload隐式转换和运算符重载
【发布时间】:2019-03-02 12:32:28
【问题描述】:

所以,我写了这样的东西

#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

我有点困惑:

  • 这是明确定义的行为,还是特定于实现?

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

【问题讨论】:

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


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

    标准中的特定规则是:

    [over.best.ics] 用于重载解决方案。 [conv.prom]积分推广。

    【讨论】:

      猜你喜欢
      • 2010-12-09
      • 2014-08-18
      • 1970-01-01
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 2013-08-25
      • 1970-01-01
      相关资源
      最近更新 更多