Правильно ли clang или gcc в этом доступе к внутреннему члену класса? - PullRequest
0 голосов
/ 09 января 2019

Следующий код компилируется и работает в clang, но завершается с ошибкой «ошибка: недопустимое использование элемента не статических данных« Outer :: a »» в gcc:

#include <functional>
#include <vector>
#include <assert.h>
#include <iostream>
#include <memory>

class Outer
{
public:
    bool a = false;

    virtual void f() = 0;

    template <typename T>
    class Inner : public T
    {
    public:
        virtual void f() override
        {
            a = true; // Note: accessed through inheritance, not through outer scope
        }
    };
};

struct Foo : Outer { };

int main()
{
    Outer::Inner<Foo> f;
    f.f();
}

Добавление «this-> a» к внутреннему классу заставляет его работать на обоих компиляторах, но мне интересно, каково правильное поведение и что стандарты говорят об этом.

Интересно, что приведенный выше код работает как часть большей базы кода в VS2017 на работе, но когда я пробую его дома с VS2017 в изоляции, он завершается с той же ошибкой, что и GCC.

Вы можете попробовать скомпилировать его здесь:

1 Ответ

0 голосов
/ 09 января 2019

Код неверен диагностика не требуется . Так что Gcc прав и дружелюбен. А отсутствие диагностики для Clang и MSVC - это просто проблема качества компилятора.

Правило соответствующего стандарта: [temp.res] / 8 :

Срок действия шаблона может быть проверен до любого экземпляра. [Примечание: Зная, какие имена являются именами типов, можно таким образом проверять синтаксис каждого шаблона. - конец примечания ] Программа некорректна, диагностика не требуется, если:

  • [..]

  • гипотетическое создание шаблона сразу после его определения было бы неправильно сформировано из-за конструкции, которая не зависит от параметра шаблона, или [...]

В теле f неквалифицированное id-выражение a не зависит от какого-либо параметра шаблона, поэтому это id-выражение должно быть разрешено в точке определения шаблона без знания какого-либо аргумента шаблона. И в этот момент это выражение плохо сформировано.


Примечание: неквалифицированное выражение-выражение (из доступа к члену класса) должно быть членом, только если оно называет члена этого класса или независимой базы [temp.dep .type] / 5

Имя является членом текущего экземпляра, если оно:

  • Неквалифицированное имя, которое при поиске относится как минимум к одному члену класса, являющегося текущим экземпляром, или его независимому базовому классу.
...