Страницы

Поиск по вопросам

четверг, 13 февраля 2020 г.

Ошибка: 'a' was not declared in this scope

#cpp #gcc #mingw #qt


Скачал последний qt 5.3.0 c MinGW 4.8.2 и удивился. (тоже самое и с qt 5.2.0 с MinGW
4.8.0)
#include 

using 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; Это правило связанно с поиском неквалифицированных имен именно в базовых классах, а не с зависимыми именами вообще. Эта деталь почему-то не затронута в принятом ответе.

Комментариев нет:

Отправить комментарий