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

相關問題