Правила поиска имени участника

#c #class #language-lawyer

#c #класс #язык-юрист

Вопрос:

Раздел 10.2 описывает правила поиска имен членов:

10.2/3:

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

10.2/4:

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

Рассмотрим следующие два примера:

 class A
{
    void foo(){ A::a; } //S(a, A)={ static const int a; }
    static const int a = 5;
}
 

и

 class A
{
    int b[A::a]; //S(a, A) is empty and the program is ill-formed
    static const int a = 5;
}
 

Каковы фактические правила вычисления S (f, C) и почему?

Ответ №1:

Для этих фрагментов кода

 class A
{
    void foo(){ A::a; } //S(a, A)={ static const int a; }
    static const int a = 5;
};

class A
{
    int b[A::a]; //S(a, A) is empty and the program is ill-formed
    static const int a = 5;
};
 

вам следует рассмотреть поиск имен, который описан в разделе 3.4 Name lookup Стандарта. Они не имеют ничего общего с приведенными вами цитатами. Хотя я могу показать, что такое S (f, C), например, для имени A::a в определении первого класса. Таким образом, S( a, A) зависит только от одного объявления static const int a = 5

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

Другое правило используется для поиска имен в функциях-членах. В первом определении класса будет найдено имя A::a .

Все это описано в разделе 3.4 Стандарта, как я уже указывал.

Что касается приведенной вами фразы, то более подходящим примером будет, например, следующее

 struct A
{
   void f( int );
};

struct B : A
{
   using f;
   void f( char );
};
 

В этом случае, если выполняется поиск по имени f, то S( f, B) будет содержать два объявления

 using f; // or void f( int );
 

и

 void f( char );
 

Комментарии:

1. Я не согласен с They have nothing common with the quotes you cited. этим, потому что в 3.4.3.1 / 1 сказано: If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-namespecifier is looked up in the scope of the class (10.2) . Это означает, что поиск имени участника будет применен в моих фрагментах кода. Я прав?

2. @Dmitry Fucintv В этом случае рассматриваются ситуации, когда класс является полным типом, то есть когда класс уже определен.

3. Но в 10.2 что-то не говорится о полноте типа класса. Поэтому я предполагаю, что эти правила применяются как к полным, так и к неполным типам классов.

4. @Dmitry Fucintv Я согласен с вами, что это место Стандарта неоднозначно.