【问题标题】:Why is this function call ambiguous?为什么这个函数调用不明确?
【发布时间】:2014-11-18 14:05:18
【问题描述】:

我正在阅读标准并试图弄清楚为什么没有强制转换就无法解析这段代码。

void foo(char c) { }

// Way bigger than char
void foo(unsigned long int) { }

int main()
{
   foo(123456789); // ambiguous
   foo((unsigned long int) 123456789); // works
}

它是这样说的:

4.13 整数转换排名[conv.rank]

每个整数类型都定义了一个整数转换等级 如下:

——任何无符号整数类型的等级应等于 对应的有符号整数类型。

——char的秩应该等于signed char和unsigned的秩 字符。

特别是,让我的小伙伴们感到不安的是,它没有说任何无符号整数类型,只是无符号字符。我的猜测是 char 通过转换被提升为无符号类型。这是真的吗?

【问题讨论】:

  • 也许 123456789U 会为你做这件事。
  • "特别是,让我的 jimmies 沙沙作响的是,它没有说任何无符号整数类型,只是无符号字符。我的猜测是 char 正在通过转换被提升为无符号类型。这是真的吗?” - 我冒着风险你误解了标准中 4.13 的重要性...char 没有被提升为unsigned...问题就像 AndreyT 所说的那样 - 123456789 是一个int 它是将其截断为 char 或将其传递为 unsigned long 显然不是更好(long 会同样糟糕 - unsigned 在这里并不重要)。
  • 尽管有这个名称,但“整数转换排名”实际上并未用于在重载解析期间对整数转换进行排名。
  • 两种转换都不是安全的——一个是有符号到无符号的,另一个是较大的类型到较小的类型——那么为什么一个不安全的操作要胜过另一个呢?
  • +1 表示“我的吉米沙沙作响”

标签: c++ integer implicit-conversion unsigned-integer integer-promotion


【解决方案1】:

它与 4.13 中定义的类型的等级关系不大。 4.13 定义了用于描述积分提升和常用算术转换的内部排名。它们本身并不直接影响重载决议。与重载解析相关的排名在“13.3.3.1.1 标准转换序列”中定义,然后在“13.3.3.2 排名隐式转换序列”中使用。

因此,它与 13.3 中定义的转换等级有关。 123456789 是您平台上 int 类型的整数文字。这意味着调用函数的charunsigned long 版本需要从intchar 或从intunsigned long 的隐式转换。在这两种情况下,我们都有“积分转换”类型的转换。这意味着在这种情况下,这两个功能同样“糟糕”。因此模棱两可。

如果其中一个函数只需要积分 promotion(与积分 conversion 相对),它将赢得决议,并且调用将被认为是明确的。但是很遗憾,您的两个函数都需要完整的转换

【讨论】:

  • 或者,换个角度看:函数调用重载不区分123456789-123456789,两者都是ints。将-123456789 转换为unsigned long 可能会丢失数据:所以一般来说,从int 转换为unsigned long 可能会丢失数据。 char 也是如此。现在,使用 123456789 的特定常量,您可以证明它不会丢失,但重载规则没有考虑到这一点:123456789 的类型在您的系统上是 int,所以 int用于进行重载解析。
猜你喜欢
  • 2016-05-18
  • 2020-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多