Поиск имени базового класса после наследования конструктора

Рассмотрим следующий код:

struct base {};

struct derived : public base {
    using base::base;
    base foo() const;  // how does name lookup on 'base' here work?
};

Интуитивно понятно, что этот код действителен, и он компилируется (проверено с помощью gcc и clang).

Тем не менее, я хотел бы понять, что в стандарте делает его действительным. В частности, я хотел бы понять, как поиск имени для base в base foo() находит тип базового класса, а не унаследованный конструктор.

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

Я начал с [class.member.lookup] p1:

Поиск имени члена определяет значение имени (id-выражения) в области видимости класса. [...] Для id-выражения поиск имени начинается в области видимости класса this

p7 говорит нам, каков результат поиска имени:

Результат поиска имени для [имя члена] f в [области видимости] C является набором объявлений S(f, C)

Я пытаюсь следовать этой процедуре с C являющийся derived, а также f быть использование base в base foo(),

"Набор деклараций" определяется в p3:

Набор для поиска f в C называется S(f, C), состоит из двух наборов компонентов: набор объявлений, набор членов с именем f; [...]

p4 говорит нам, что входит в набор объявлений:

Если C содержит декларацию имени f набор объявлений содержит каждое объявление f объявлено в C это удовлетворяет требованиям языковой конструкции, в которой происходит поиск.

using base::base это объявление имени base (f) в derived (C). В этом параграфе приводятся примеры того, что означает, что объявление не удовлетворяет требованиям языковой конструкции, в которой происходит поиск, но там нет ничего, что могло бы исключить using base::base из этого поиска.

Далее дальше вниз по p3 нам рассказывают, как обрабатываются using-объявления в наборе объявлений:

В наборе объявлений использование-объявлений заменяется набором назначенных членов, которые не скрыты или не переопределены членами производного класса.

Так что участники делают using base::base назначить? Мне кажется, что ответили [class.qual] p2:

При поиске, в котором имена функций не игнорируются, а спецификатор вложенного имени назначает класс C:

  • если имя указано после спецификатора вложенного имени, при поиске в C, является введенным именем класса C, или же

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

вместо этого имя считается именем конструктора класса C,

Существует сноска, поясняющая, что означает "поиск, в котором имена функций не игнорируются":

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

Ни один из этих случаев не подходит для поиска имени, о котором идет речь, поэтому мне кажется, что этот параграф применим и говорит, что using base::base обозначает конструктор (что также является интуитивно понятным, учитывая, что это объявление наследующего конструктора).

Найдя объявление (обозначающее конструктор базового класса) в области видимости производного класса, мы продолжаем [class.member.lookup] p4:

Если результирующий набор объявлений не пустой, набор подобъектов содержит C Сам, и расчет завершен.

Таким образом, поскольку поиск имени нашел результат в области производного класса, он не переходит к поиску в области базового класса (где он найдет имя введенного класса). base). [В качестве отступления, даже если поиск по имени продолжался в области видимости базового класса, я не вижу ничего, что могло бы устранить неоднозначность между конструктором и именем введенного класса ].

Где мои рассуждения идут не так?

1 ответ

Решение

Стандарт делает все возможное, чтобы указать, что конструктор не имеет имени. Его нельзя найти по имени, потому что у него нет имени.

C++ 11 §12.1 / 1

конструкторов нет имен.

C + 11 §12.1 / 2

" Поскольку конструкторы не имеют имен, они никогда не обнаруживаются при поиске имен.

Другие вопросы по тегам