У меня есть этот код (проблема ромб):Алмаз смерти и разрешения Scope оператора (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();
}
Я хочу назвать print()
в Top
классе.
Когда я пытаюсь скомпилировать его, я получаю ошибку: 'Top' is an ambiguous base of 'Bottom'
на этой строке: b.Right::Top::print();
Почему это неоднозначно? Я прямо указал, что хочу Top
от Right
, а не от Left
.
Я не хочу знать, КАК это сделать, да, это может быть сделано со ссылками, виртуальным наследованием и т. Д. Я просто хочу знать, почему b.Right::Top::print();
неоднозначный.
Это неоднозначно с помощью * «Если оператор доступа к члену класса, включая неявный« this-> », используется для доступа к нестационарному элементу данных или нестатической функции-члена, ссылка плохо сформирована, если левый операнд (рассматривается как указатель в ".«Операторский случай» не может быть неявно преобразован в указатель на класс именования правильного операнда «*, 11.2p6. Обратите внимание, что класс именования« A », но« D * »не может быть неявно преобразован в' A * '. –
Семантика здесь заключается в том, что вы рассказываете, какую функцию вы хотите вызывать с помощью 'B :: A :: tell'. Вы помогаете компилятору с помощью' D :: tell', то есть с поиском имени. 't указать подобъект, который он должен использовать, - у него будет два варианта: спуститесь по дороге к 'A' над' B' или над 'C', и вы получите сообщение об ошибке. –
Есть две« основные »проверки неоднозначности которые выполняются в контекстах, которые работают с объектами во время выполнения: один в 5.2.5p5, и тот, который укусит вас здесь в 11.2p6. Тот, который в 5.2.5p5 отклоняет 'd.tell()', если вы должны удалить все функции tell кроме класса «A», поскольку класс именования тогда «D», но 'tell' будет прямым членом' A', а 'A' является двусмысленным. Если вы затем скажете' DB :: A :: tell() ', он хорошо сформирован 5.2.5p5 , но плохо сформировался на 11.2p6. Эти проверки дополняют друг друга и важны для правильной работы в системе типов. –