Странное поведение объявления об использовании

пожалуйста, смотрите следующий код

struct A { using type = int; };
struct B : private A {};
struct C : B { using base_type = A; };

Все gcc 6.1, clang 3.8 и msvc 2015 update 3 отказываются компилировать это, так как A не доступно имя внутри C поскольку A является частной базой B, Кажется, что GCC думает A в using base_type = A ссылается на конструктор по умолчанию A, MSVC и лязг, кажется, нет.

Возможно, ошибка компиляции связана с внедрением имен, вызванных наследованием (потому что изменение using base_type = A в using base_type = ::A заставить все компиляторы работать нормально), но я хочу знать, является ли эта странная ошибка стандартом.

Конкретнее,

  1. Как я поняла, не понравится A::type, A это просто имя класса (хотя gcc неверно интерпретирует его как имя функции), которое вводится в C не внутри A ни B, Почему это имя считается частным B?
  2. Следует ли считать эту ошибку компиляции ошибкой, или это крайний случай спецификаций стандарта?

26

Решение

Согласно правилу поиск безусловного имени:

(акцент мой)

Для неквалифицированного имени, то есть имени, которое не отображается справа от оператора разрешения контекста :: поиск имени проверяет области, как описано ниже, пока не найдет хотя бы одно объявление любого вида, в это время поиск останавливается и дальнейшие области не рассматриваются.

Итак, имя A будет сначала найден в области видимости базового класса, имя в глобальном пространстве имен здесь не будет рассматриваться. После этого выполняется проверка прав доступа, а затем компиляция не удалась.

А также ::A указывает имя в глобальной области видимости и решает проблему, что делает его поиск подходящего имени.

28

Другие решения

Публикация моего комментария как ответа (больше похоже на ответ, чем на комментарий):

Я предполагаю, что это связано с тем, как поиск имени для Aвнутри C работает. Сначала он проверяет, объявлено ли что-либо с именем A в объеме C Перед использованием. Поскольку он не находит, он проверяет его в объеме B так как это базовый класс. А также в случае он не находит A в области видимости Bs, это будет выглядеть в global namespace, Но каким-то образом частное наследство A от B останавливается при втором поиске, т. е. в рамках B, Поскольку он работает с использованием fully qualified имя, которое заставляет меня думать, что реальная проблема должна быть в том же духе

2

По вопросам рекламы [email protected]