2012-02-28 62 views
1

考慮下面的示例代碼:歧義而重載轉型操作

#include <iostream> 

using namespace std; 

class dummy 
{ 
    private: 
     int y; 

    public: 
     dummy(int b = 0) : y(b) { 
     } 

     friend ostream& operator<<(ostream& os, const dummy& obj); 
}; 

ostream& operator<<(ostream& os, const dummy& obj) 
{ 
    os << obj.y; 
    return os; 
} 

class sample 
{ 
    private: 
     int x; 

    public: 
     sample(int a = 0) : x(a) 
     { 
     } 

     operator dummy() 
     { 
     dummy d(100); 
     return d; 
     } 

     operator int() 
     { 
     return x; 
     } 
}; 

int main() 
{ 
    sample ob1(5); 
    dummy d; 

    //d = ob1; //Line1 
    d = (dummy)ob1; //Line2 

    cout << d << "\n"; 
} 

在1號線,隱式轉換完成。我明白這種情況下隱式投射是如何工作的。編譯器不提供任何錯誤。

但是在Line2中,sample對象的顯式類型轉換爲dummy對象。但編譯器給出了以下錯誤。

error: call of overloaded `dummy(sample&)' is ambiguous

note: candidates are: dummy::dummy(const dummy&)

note: dummy::dummy(int)

問題:

  1. 爲什麼發生這些錯誤?

  2. 我不明白錯誤信息的含義。爲什麼在錯誤中提到的dummy類的候選函數?

+2

[?爲什麼構造不叫給定鑄造運營商(HTTP的可能重複://計算器。 com/questions/6120240/why-constructor-is-not-called-for-given-casting-operator) – iammilind 2012-02-28 05:26:01

+0

誰曾投票結束這個問題並不知道問題的重要性。請看看我問過的問題 – 2012-02-28 05:33:28

回答

5

線:

d = (dummy)ob1 

嘗試執行以下操作:

  1. obj1構建dummy對象
  2. 分配該臨時dummy目的是d

第1部分是導致問題的原因。爲了構造臨時的dummy對象,編譯器必須搜索某種方法將obj1轉換爲dummy可以從中構建的類型。報告認爲,有兩種方法可以做到這一點:

  1. 呼叫operator int
  2. 呼叫operator dummy

你不告訴它,你希望它採取這兩個選擇中的一個,所以代碼不明確。


你的問題可以重新創建(刪除無關的部分)如下:

struct t_1 {}; 
struct t_2 {}; 
struct sample { 
    operator t_1() const{ return t_1(); } 
    operator t_2() const{ return t_2(); } 
}; 
void f(t_1) {} 
void f(t_2) {} 
int main() { 
    sample obj1; 
    //overload resolution will fail 
    //disambiguate with f(obj1.operator t_1()) or f(obj1.operator t_2()) 
    f(obj1); 
} 
+0

那麼爲什麼編譯器不會抱怨隱式轉換d = ob1? – 2012-02-28 05:37:07

+1

'd = obj1'調用'd'的賦值操作符。對於'd',沒有賦值運算符,它需要一個'int'參數,所以只考慮'operator dummy'。對於'(dummy)obj1'(爲了與多參數構造函數保持一致,應該將其重寫爲'dummy(obj1)')構造一個臨時對象,但是不清楚'int'還是'dummy const&應該使用'構造函數。 – Mankarse 2012-02-28 05:39:58

+0

'operator int'和'operator dummy'是類'sample'的類型轉換操作符。但看看錯誤消息中的候選函數。他們指的是「虛擬」類。這是爲什麼? – 2012-02-28 05:41:13