2013-01-16 73 views
13

在下面的代碼中,如果由於含糊不清而定義了多個演員操作符,我會希望得到編譯器錯誤。重載的演員操作符的優先級

#include <iostream> 
#include <sstream> 

struct A 
{ 
    operator const char*() { return "hello world\n"; } 
    operator float()  { return 123.0F; } 
    //operator int()   { return 49; } 
}; 

int main() 
{ 
    A a; 
    std::stringstream ss; 
    ss << a; 
    std::cout << ss.str(); 
    return 0; 
} 

相反,只要只有一個數字轉換運算的定義則沒有錯誤,沒有警告編譯,並在數字轉換時優先使用operator const char *()。所聲明的操作員的順序沒有區別。

然而,如果operator int()operator float()都然後定義我得到了我從一開始就預計:

'operator <<' is ambiguous

是否有強制轉換優先規則,或者爲什麼編譯器選擇默認情況下數字投?我明白我應該明確說出我的意思,但我的問題是編譯器默認選擇。


編輯:使用編譯器MSVC 2010

+0

我不會依賴於有優先權。輸入你的意思。只需使用明確的演員。 'ss << static_cast (a);' – andre

+0

我編譯了你的例子,g ++給了我「錯誤:'ss << a'」中'operator <<'的模糊超載。所以,至少g ++正在按預期工作。 –

+1

這似乎是編譯器相關的。你正在使用哪種編譯器? – SztupY

回答

4

轉換的排名根據§C++標準的13.3.3.1。具體而言,與您的示例相關的用戶定義的轉換序列由§13.3.3.1.2/1規定:

「用戶定義的轉換序列由一個初始標準轉換序列和一個用戶定義轉換組成(12.3),然後是第二個標準轉換序列[...]如果用戶定義的轉換由轉換函數(12.3.2)指定,則初始標準轉換序列將源類型轉換爲轉換功能「。

這裏所有轉換序列包括:

  1. 一個虛構轉換到源類型的轉換函數的隱式對象參數的;
  2. 用戶定義的轉換;
  3. 身份轉換爲輸入類型operator <<

這些轉換序列都具有相同的等級。因此,的呼叫應該是模糊的。如果不是,對我來說這是一個編譯器錯誤。

+1

您的答案具有誤導性,因爲無論如何都不應該有任何*「第二標準轉換」*,因爲用戶定義的轉換直接轉換爲必要類型。所以是的,這個電話應該是模棱兩可的,但不是因爲你在第三段中給出的理由。 –

+0

@ChristianRau:如果我正確理解13.3.3.1.2/1所說的,用戶定義的轉換總是*三步轉換,其中第一步可能是虛構的:「初始標準轉換序列將源鍵入到轉換函數的隱式對象參數中。「 –

+1

是的,但初始和第二次標準轉換隻能是空操作。在這種情況下,目標類型已經由(中)用戶定義的轉換達到。所以是的,它們都具有相同的排名,但並不是因爲整數浮點或指針轉換具有相同的排名(這裏沒有關係),而是因爲它們都包含相同的初始標準轉換,其次是用戶定義的轉換**,然後是相同的(無操作)第二標準轉換**。 –