[英]Diamond of death and Scope resolution operator (c++)
我有此代碼(鑽石問題):
#include <iostream>
using namespace std;
struct Top
{
void print() { cout << "Top::print()" << endl; }
};
struct Right : Top
{
void print() { cout << "Right::print()" << endl; }
};
struct Left : Top
{
void print() { cout << "Left::print()" << endl; }
};
struct Bottom: Right, Left{};
int main()
{
Bottom b;
b.Right::Top::print();
}
我想在Top
類中調用print()
。
當我嘗試對其進行編譯時,出現錯誤: 'Top' is an ambiguous base of 'Bottom'
此行上'Top' is an ambiguous base of 'Bottom'
: b.Right::Top::print();
為什么模棱兩可? 我明確指定要從Right
Top
Right
而不是“ Top
Left
。
我不想知道如何去做,是的,它可以通過引用,虛擬繼承等來完成。我只是想知道為什么b.Right::Top::print();
曖昧。
為什么模棱兩可? 我明確指定要從
Right
Top
Right
而不是“Top
Left
。
那是您的意圖,但實際上並非如此。 Right::Top::print()
明確命名您要調用的成員函數,即&Top::print
。 但是它沒有指定我們在b
哪個子對象上調用該成員函數。 您的代碼在概念上等效於:
auto print = &Bottom::Right::Top::print; // ok
(b.*print)(); // error
選擇print
的部分是明確的。 從b
到Top
的隱式轉換是模棱兩可的。 您必須通過執行以下操作來明確消除前進的方向:
static_cast<Right&>(b).Top::print();
范圍解析運算符是左關聯的(盡管它不允許使用括號)。
因此,雖然您想在B
內部引用A::tell
,但id-expression卻在B::A
內部tell
,這就是A
,這是模棱兩可的。
解決方法是先強制轉換為明確的基B
,然后再次強制轉換為A
語言咨詢:
[basic.lookup.qual] / 1說,
在將
::
作用域解析運算符應用於表示其類,名稱空間或枚舉的嵌套名稱說明符之后,::
類或名稱空間成員或枚舉器的名稱 。
嵌套名稱說明符的相關語法為:
嵌套名稱說明符:
類型名稱
::
嵌套名稱說明 標識符
::
因此,第一個嵌套名稱說明符是B::
並且在其中查找A
然后B::A
是表示A
的嵌套名稱說明符,並在其中查找tell
。
顯然,MSVC接受該示例。 它可能具有非標准擴展,可以通過在此類說明符中回溯來解決歧義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.