#cpp #gcc #mingw #qt
Скачал последний qt 5.3.0 c MinGW 4.8.2 и удивился. (тоже самое и с qt 5.2.0 с MinGW 4.8.0) #includeusing namespace std; template class Super{ class A{ protected: int a; }; class B : public A{ int b; B(){ b = a; } }; }; int main() { cout << "Hello World!" << endl; return 0; } Не работает. Выдаёт: C:\***\main.cpp:14: ошибка: 'a' was not declared in this scope b = a; ^ Хотя, убрать строку template , то всё работает. Причём приведённый выше код без изменений работает, например, в Visual Studio 2008. Это баг MinGW или же это так и надо/допустимо? Кстати, нормально работает с MinGW и если писать this->a.
Ответы
Ответ 1
Кажется, я понял. Вот тут обсуждают похожую проблему. В вашем случае ситуация такова. b является зависимым именем. Компилятор должен понять значение этого зависимого имени до подстановки T. (Посмотрите детали и обсуждение в этом вопросе). Поскольку он не может, разработчики стандарта решили убрать зависимые имена из области видимости внутри шаблона. Поэтому вам приходится указывать явно, что именно вам нужно. Таким образом, баг в старом Visual Studio, их реализация не вполне соответствовала стандартам. (В новом Visual Studio уже соответствует.) Я считаю, что язык C++ неоправданно избыточно сложен. Вы натолкнулись на одно из таких мест.Ответ 2
При выполнении поиска неквалифицированных имен (unqualified name lookup), в рассмотрение не включаются базовые классы, зависящие от параметров текущего шаблона. В данном случае A - это на самом деле Super::A и зависит от параметра шаблона T. По этой причине имя a из базового класса A не находится компилятором. Использование квалифицированого имени или явного синтаксиса доступа к члену класса устранит ошибку int b = A::a; int b = this->a; Это правило связанно с поиском неквалифицированных имен именно в базовых классах, а не с зависимыми именами вообще. Эта деталь почему-то не затронута в принятом ответе.
Комментариев нет:
Отправить комментарий