32

我正在阅读标准,并试图找出为什么这个代码不会被解决没有演员。为什么这个函数调用不明确?

void foo(char c) { } 

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

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

这里是这样说的:[conv.rank]

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

4.13整数转换排名:

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

- 字符的排名应等于有符号字符和无符号字符的排名。

特别是,我的吉姆斯沙沙什么是它没有说任何无符号整型,只是无符号字符。我的猜测是,通过转换将char提升为无符号类型。这是真的?

+3

也许123456789U会为你做。 – WhozCraig 2014-09-24 07:30:45

+0

“特别是,我的吉姆斯的沙沙声是它没有说任何无符号的整数类型,只是无符号的char。我的猜测是char通过转换被提升为无符号类型,这是真的吗?” - 我认为你误解了标准中4.13的意义......'char'没有被提升为'unsigned' ......问题在于AndreyT说 - 123456789是一个int类型,它是不是明显更好地将其截断为'char'或将其作为'unsigned long'传递('long'将会同样糟糕 - 'unsigned'在这里并不重要)。 – 2014-09-24 07:37:02

+1

尽管名称存在,但在重载解析期间,“整数转换排名”实际上并未用于对整数转换进行排名。 – 2014-09-24 09:08:59

回答

51

它与4.13中定义的类型没有什么关系。 4.13定义了用于描述积分促销和常规算术转换的内部排名。它们本身不直接影响重载分辨率。有关重载分辨率的排名在“13.3.3.1.1标准转换序列”中定义,然后在“13.3.3.2排列隐式转换序列”中使用。

因此,它是根据13.3定义的转换等级。 123456789是您平台上的int类型的整数字面值。这意味着调用charunsigned long版本的函数需要从intchar或从intunsigned long的隐式转换。在这两种情况下,我们都有“积分转换”类型的转换。这意味着这两种功能在这种情况下同样“不好”。因此含糊不清。

如果这些功能需要一个区区整体推广(相对于整体转换),它会赢得分辨率和通话将被视为明确的。但是,唉你的两个功能都需要积分转换

+1

或者,看看它的另一种方式:函数调用过载不区分'123456789'和'-123456789',它们都是'int's。将'-123456789'转换为'unsigned long'可能会丢失数据:所以通常情况下,从int到'unsigned long'的转换可能会丢失数据。 'char'也是如此。现在,使用'123456789'的特定常量可以证明它不会丢失,但超负荷规则并没有考虑到这一点:在您的系统中'123456789'的类型是'int',所以'int'被用来做重载分辨率。 – Yakk 2014-09-24 17:46:31

相关问题