2010-11-09 71 views
3

$ 7.3.3/14(C++ 03)重載分辨率/歧義名稱查找(其中之一)

struct A { int x(); }; 
struct B : A { }; 
struct C : A { 
    using A::x; 
    int x(int); 
}; 
struct D : B, C { 
    using C::x; 
    int x(double); 
}; 
int f(D* d) { 
    return d->x(); // ambiguous: B::x or C::x 
} 

在 'F' 的代碼的註釋表示一個可以預期B之間」歧義:: x'或'C :: x'。

然而,與克編譯++(ideone)或科莫錯誤略有不同。這些錯誤,而不是表明B :: X歧義或C :: X表明一個事實,即A是d區的含糊的基礎

prog.cpp: In function ‘int f(D*)’: prog.cpp:16: error: ‘A’ is an ambiguous base of ‘D’

而且

"ComeauTest.c", line 21: error: base class "A" is ambiguous return d->x(); // ambiguous: B::x or C::x

在$ 10.2,打算到名字查找規則,我感覺到代碼片段中的評論並不真正正確。這個錯誤的確首先涉及基類「A」的模糊性,而不是其他任何內容(例如重載分辨率的模糊性)。有什麼想法嗎?

+1

有趣的是,視覺C++編譯10.0以上,選擇在B A子對象...我可以理解它,如果它在C.選擇的子對象看來,g ++以及科莫第一解決成員函數爲A :: x(),然後他們發現d-> A :: x()是不明確的。但是,有趣的是,Visual C++ 10.0甚至可以編譯! – 2010-11-09 03:39:47

+0

@Alf P. Steinbach:是的。我也很驚訝 – Chubsdad 2010-11-09 03:49:26

+0

因爲我沒有C++ 03編譯器,所以我希望這個問題能夠被容忍...在結構D中使用virtual關鍵字如何:virtual B,C或struct D:虛擬C,虛擬B? – JimR 2010-11-09 07:47:41

回答

2

這是通過一個捻名的查找在C++ 03引起的:檢查一個明確的子對象是類構件的一部分在C++ 03中查找名稱。查找在C++ 03會發現d :: X和C :: x和A :: x,其中A :: x匹配,而是與類型A的兩個不同的子對象

相關聯在C++ 0X ,檢查一個明確的子對象現在成爲相應子條款的一部分,請參閱DR #39x直接是其成員的類是一個模糊的基 - 因此第5條將導致編譯錯誤,而不是第10條。

請注意,該評論是關於A的子對象的。還有就是A一個子對象是越過道路B,和A另一個子對象是越過道路C。這就是爲什麼評論說「B::xC::x」。可以通過僅嘗試轉換爲其類類型來確定是否存在相同類類型的多個子對象,而忽略可訪問性問題:如果轉換不明確,則子對象會多次出現。

+0

是的。我記得以前有關這個的討論。然而,這一次我的觀點是,如果代碼示例中的註釋非常合適。出於某種原因,我感覺'//不明確:B :: x或C :: x'是在重載的情況下,尤其是當樣本中有兩個重載'x'可見時 – Chubsdad 2010-11-09 07:36:54

+0

@Chubsdad註釋不會討論'B'或'C'中的聲明,但是關於類型A的子對象的選擇。如果你寫了'd-> B :: x()'或'd-> C :: x() ''''''''''''''''''''''''''''''''''''''''你不會含糊不清,因爲查找分別從'B'和' – 2010-11-09 21:03:36

+0

在C++ 0x中,規範更爲清晰:有三個明確區分的步驟:1)查找聲明(10.2)並執行重載解析。這會找到'A :: x'。 2)檢查對象表達式是否可以(明確地)轉換爲命名類'(在a-> c中命名類和對象表達式是'a'的類型,但是在'a-> b :: c'中,命名類是'b') - 11.2/6。 3)檢查聲明直接是其成員的類是命名類的明確基類 - 5.2.5/5。你的代碼違反了'3)'。 – 2010-11-09 21:07:00

0

鏘++有些給出由g產生的誤差的組合++和科莫

C:\Users\SUPER USER\Desktop>clang++ chubsdad.cpp 
chubsdad.cpp(12) : error: ambiguous conversion from derived class 'D' to base class 
     'A': 
    struct D -> struct B -> struct A 
    struct D -> struct C -> struct A 
    return d->x(); // ambiguous: B::x or C::x 
     ^
1 error generated. 
+0

哦,好的。謝謝。我不確定如果這回答我的問題關於在代碼段 – Chubsdad 2010-11-09 05:06:58

+0

中的評論的適當性和真正的意圖我認爲''不明確:B :: x或C :: x'結果從''A是一個模糊的基礎'D'。所以在代碼中的評論是正確的恕我直言。 – 2010-11-09 05:08:44