1

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

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). [В стороне, даже если поиск по имени продолжался в области базового класса, я не вижу ничего, что могло бы устранить смещение между конструктором и именем с введенным классом].

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

ответ

4

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

C++ 11 §12.1/1

Конструкторы не имеют имен.

C + не 11 §12.1/2

Поскольку конструкторы не имеют имен, они не нашли во имя поиска.

+0

Что это за бит в '[class.qual] p2', который говорит, что« вместо этого имя называется именем конструктора », тогда? – HighCommander4

+0

@ HighCommander4: предположительно речь идет о применении функциональной нотации для вызова конструктора. –

+0

Но что исключает этот абзац от применения к 'using base :: base'? – HighCommander4