答案是鐺是正確的。但是,根據標準,代碼也可能會失敗。
如果你看看11.2p5它有一個相關的說明(是的,我知道筆記非規範):
[注:這個類可以是明確的,例如,當一個合格的-ID是使用, 或隱式,例如,當使用類成員訪問運算符(5.2.5)時 (包括添加了隱含「this->」的情況)。 如果012xx成員訪問運算符和合格ID都用於命名成員 (如p->T::m
中所示),則命名該成員的類是由 指定的類。qualified-id的嵌套名稱說明符即T)。末端注意 ]
這是什麼意思音符,是,如果你然後添加到this->
C::x = 2;
C
是類命名的成員和gcc 4.7.2 correctly fails when this is the case。
現在的問題是誰是爲C::x
命名成員的班級? 該naming class
由相同11.2p5
指定:由類
到成員的接入會受到影響,其中所述構件是 命名。 這個命名類是查找並找到成員名稱爲 的類。
現在,類成員名稱查找在10.2指定,閱讀這一切後,我的結論是x
是子對象集工會按:
否則,新的S(f,C)是一個查找集,其中共享集 聲明和子對象集的聯合。
這意味着根據構件查找規則x
可以是從B
或A
!這使得代碼不良形成:Name lookup can result in an ambiguity, in which case the program is ill-formed.
然而,這種不確定性可以被解析爲每10.2p8:
歧義往往可以通過與同級車 名排位賽的名稱來解決。
而且從Clang source,我們可以看到這是他們選擇這樣做:
// If the member was a qualified name and the qualified referred to a
// specific base subobject type, we'll cast to that intermediate type
// first and then to the object in which the member is declared. That allows
// one to resolve ambiguities in, e.g., a diamond-shaped hierarchy such as:
//
// class Base { public: int x; };
// class Derived1 : public Base { };
// class Derived2 : public Base { };
// class VeryDerived : public Derived1, public Derived2 { void f(); };
// void VeryDerived::f() {
// x = 17; // error: ambiguous base subobjects
// Derived1::x = 17; // okay, pick the Base subobject of Derived1
// }
但是,請注意上述報價的措辭can
:often can be resolved
。這意味着他們不一定要解決。所以,我認爲根據標準,代碼應該失敗,因爲模糊或作爲私人成員訪問失敗。
編輯
有關於can
解釋一些競爭和是否一個歧義發生在這裏。我發現Defect report 39. Conflicting ambiguity rules談到了這個問題。
編譯[有](http://ideone.com/clone/VvWyUW)(儘管同樣的編譯器)。似乎GCC的錯誤呢? – 2013-03-13 23:37:44
有趣的是:相同的編譯器,不同的結果。無論如何,我無法想象任何東西 – 2013-03-13 23:39:34
g ++ 4.7.2成功地在兩個位置編譯相同的源代碼。 – Aneri 2013-03-13 23:39:51