#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 Я согласен с вами, что это место Стандарта неоднозначно.