Рассмотрим следующий код:Поиск имени базового класса после наследования конструктор
struct base {};
struct derived : public base {
using base::base;
base foo() const; // how does name lookup on 'base' here work?
};
Интуитивно ясно, что этот код является действительным, и он компилируется (протестировано с GCC и лязгом).
Однако я хотел бы понять, что в стандарте делает его действительным. В частности, я хотел бы понять, как поиск имен для base
в base foo()
находит тип базового класса, а не унаследованный конструктор.
Вот мой анализ стандартной формулировки, показывающий, что он должен разрешить конструктору. Вероятно, это неправильно, но я хотел бы понять, где я ошибаюсь.
Я начал с [class.member.lookup] p1
:
Имя пользователя поиска определяет значение имени (ID-выражения) в области видимости класса. [...] Для Ид выражения, поиск имени начинается в классе сферы
this
p7
говорит нам, что результат поиска имя является:
Результат поиска имени для [имя члена]
f
в [класс сфера]C
является декларация набор S (F, с)
Я tryi ng для выполнения этой процедуры с C
, являющимся derived
, и f
является использование base
в base foo()
.
"Декларация набор" определен в p3
:
поиска устанавливается для
f
вC
, называется S (F, С), состоит из двух компонентов наборов: декларации установить , набор элементов с именемf
; [...]
p4
говорит нам, что входит в набор декларации:
Если
C
содержит объявление имениf
множество декларация содержит каждое заявление оf
заявил вC
что удовлетворяет требования языковой конструкции, в которой происходит поиск.
using base::base
является декларацией имени base
(f
) в derived
(C
). В параграфе далее приводятся примеры того, что означает объявление , а не, чтобы удовлетворить требованиям языковой конструкции, в которой происходит поиск, но там ничего нет, что исключает using base::base
из этого поиска.
Далее, далее вниз в p3
мы рассказывали, как с использованием деклараций в наборе декларации обрабатываются:
В наборе декларации, с помощью деклараций заменяются набором назначенный члены, которые не скрыты или переопределены членами производного класса
И что же делать членам using base::base
? Мне кажется, так это ответил [class.qual] p2
:
В результате поиска, в котором функционируют имена не игнорируются и имя вложенной спецификатор назначает класс
C
:
если имя указанному после вложенного имени-спецификатора, при поиске в
C
, является введенным классомC
, илив используя декларацию, которая является членом декларацией, если имя, указанное после вложенного-именем-спецификатора является тем же самым, как идентификатором [...] в последнем компоненте вложенное-имя-спецификатор
имя вместо этого считается назвать конструктор класса
C
.
Существует сноска, в котором разъясняется, что такое «поиск, в котором функционируют имена не игнорировали» означает:
Lookups, в которых функционируют имена игнорируются включают имена появляются в вложенным имя спецификатора, a специфицированный тип-спецификатор, или базовый указатель.
Ни один из них не имеет место для имени поиска в вопросе, так что мне кажется, что касается этого пункта, и говорит, что using base::base
обозначает конструктор (который также является то, что вы ожидали бы интуитивно, учитывая, что это наследование конструктора конструктора).
Найдя декларацию (обозначающую конструктор базового класса) в производном классе сфере, мы продолжаем следующий [class.member.lookup] p4
:
Если результирующий набор декларации не пусто, то множество подобъектов содержит
C
самих, и расчет завершено.
То есть, поскольку поиск имени нашел результат в производном классе сферы, он не идет смотреть в базовом классе сферы (где было бы найти имя-инъекции класса base
). [В стороне, даже если поиск по имени продолжался в области базового класса, я не вижу ничего, что могло бы устранить смещение между конструктором и именем с введенным классом].
Где мои рассуждения идут не так?
Что это за бит в '[class.qual] p2', который говорит, что« вместо этого имя называется именем конструктора », тогда? – HighCommander4
@ HighCommander4: предположительно речь идет о применении функциональной нотации для вызова конструктора. –
Но что исключает этот абзац от применения к 'using base :: base'? – HighCommander4