Как работает компилятор в случае ошибки: ссылка на "mytype" неоднозначна
Я создал один сценарий, где я хочу помочь. Ниже приведен пример тестового приложения для того же.
#include <iostream>
using namespace std;
class A
{
public:
typedef int mytype;
mytype GetInt() { return 1;}
};
class B
{
public:
typedef char mytype;
};
class C : public A, public B
{
};
class D : public C
{
public:
void scenario()
{
mytype m = GetInt();
}
};
int main()
{
D d1;
d1.scenario();
return 0;
}
Компиляция кода с использованием: g++ tmp.cpp
Error:
tmp.cpp:27:9: error: reference to ‘mytype’ is ambiguous
mytype m = GetInt();
^
tmp.cpp:15:18: note: candidates are: typedef char B::mytype
typedef char mytype;
^
tmp.cpp:8:17: note: typedef int A::mytype
typedef int mytype;
^
tmp.cpp:27:16: error: expected ‘;’ before ‘m’
mytype m = GetInt();
Как видно из кода, GetInt() определен только в классе A, поэтому я считаю, что mytype будет взят только из класса A. Но это не так согласно журналу ошибок.
Мы можем решить эту проблему, добавив область видимости класса A, как
A::mytype m = GetInt();
Я хочу знать о: Как ведёт себя компилятор в этом случае? Есть ли флаг компилятора муравья, который решит эту ошибку в случае gcc?
1 ответ
[dcl.typedef]/ р6
В заданной области видимости спецификатор typedef не должен использоваться для переопределения имени любого типа, объявленного в этой области для ссылки на другой тип.
GetInt
может быть определено в A
но typedef
s в базовых классах приведут конфликт в действие при разрешении имени в scenario()
(ср. [class.member.lookup]), так как это неквалифицированный поиск.
Такое поведение определено и ожидается. Я не знаю ни одного флага, который вы могли бы использовать для достижения своей цели. Либо перейдите к поиску квалифицированного имени, как вы уже обнаружили, либо используйте auto
вывод типа, как указал Иоахим.