2012-10-09 50 views
3

爲什麼我們沒有看到代碼波紋管的「未定義調用重載函數」錯誤?只是因爲int是一個內置類型?在標準的哪裏可以找到轉換爲內置類型的保證,比如在代碼波紋中?......謝謝!函數過載和類型轉換分辨率

#include <iostream> 
using namespace std; 

class B { 
public: 
operator int(){ return 0; } 
}; 

class A { 
public: 
A(int i) { }; 
}; 

void f (int i) { cout << "overload f(int) was used!";}; 
void f (A a) { cout << "overload f(A) was used!" ;}; 


int main() { 
    B b; 
    f(b); 
} 
+1

你有沒有試過A可以直接從B構造出來,加入'A :: A(const B&)'? – PiotrNycz

+0

*未定義調用超載函數*,你的意思是*含糊* *?未定義的錯誤在編譯器匹配符號但觸發器未找到時觸發。 –

+0

@大衛是的,我的意思是「模棱兩可」。謝謝。 – alexandreC

回答

7

它與內置類型無關。您爲B定義了operator int。這意味着您已經提供了從Bint的用戶定義轉換。根據標準的12.3.4,「最多隻有一個用戶定義的轉換(構造函數或轉換函數)隱式應用於單個值。」這就是爲什麼它不會轉換爲A,因爲這需要兩次隱式轉換。

準確確定發生這種情況的規則有些複雜,所以很多人建議您避免提供用戶定義的轉換。定義這些的另一種方式是爲構造函數提供一個參數;您可以在開始時添加explicit以避免其隱式應用。

當您致電f(b)時,編譯器將您提供的轉換應用於將b轉換爲int。如果要將其轉換爲A,則必須定義從BA的轉換,或者明確應用其中一種轉換,如f(int(b))f(A(b))

+2

ISO標準12.3.4:「最多隻有一個用戶定義的轉換(構造函數或轉換函數)隱式應用於單個值。」 –

+0

^您應該將此添加到答案中。 –

+1

@LuchianGrigore:我的印象是,如果不是基本的中間語言知識...... :)順便說一句,*放肆*可能不是你要找的單詞。 –