В стандарте C ++ 14, [basic.scope.hiding], пункт 2 (3.3.10.2), говорится:
Имя класса или имя перечисления может быть скрыто по именипеременная, член данных, функция или перечислитель, объявленные в той же области действия . Если имя класса или перечисления и переменная, член данных, функция или перечислитель объявлены в той же области действия (в любом порядке) с тем же именем, имя класса или перечисления будет скрыто везде, где переменная,Имя члена данных, функции или перечислителя является видимым.
Меня беспокоит формулировка "та же область действия". Действительно, в следующем фрагменте кода, в каких случаях класс C
и переменная C
объявляются в одной и той же области видимости?
namespace case_1 {
int C;
class C;
// Here C refers to variable
}
namespace case_2 {
class C;
namespace nested {
int C;
// Here C refers to variable
}
}
namespace case_3 {
int C;
namespace nested {
class C;
// Here C refers to class
}
}
namespace case_4 {
enum Enum { A, B, C };
class C;
// Here C refers to enumerator
}
Гипотеза 1: «одна и та же область действия» означает «тот же блок "
Если мы придерживаемся этой гипотезы, случай 1 должен касаться правила 3.3.10.2. Что насчет случая 2? Я полагаю, что оно охватывается правилом 3.3.10.1:
Имя может быть скрыто явным объявлением того же имени во вложенной декларативной области или производном классе.
Кроме того, эта гипотеза хорошо объясняет случай 3, где имя класса скрывает имя переменной (а не обратное), но не может объяснить случай 4. Действительно, перечислитель C
объявлен в другом блоке, чем класс C
но класс все еще скрыт.
Гипотеза 2: «объявлено в той же области» означает «имеет точно такую же область»
Если эта гипотеза верна, ни один случай, описанный в моем коде, не являетсяобеспокоен правилом, потому что невозможно, чтобы два имени имели одинаковую область видимости. Даже переменная в case_1
имеет другую область видимости, чем класс. Действительно, область действия имени переменной начинается после ее объявления, то есть перед именем класса.
Гипотеза 3: «объявлено в той же области» означает «одно имя объявлено внутри области действия другого»
Если эта гипотеза верна, все описанные выше случаи должны быть охвачены правилом 3.3.10.2. Действительно, в case_1
и case_3
класс C
объявлен в области действия переменной C
;в case_2
, C
переменная объявлена в области видимости C
class;и в case_4
класс C
объявлен в области действия перечислителя C
. Однако case_3
не следует правилу, потому что именно эта переменная должна «победить» и оставаться видимой.
Как вы можете видеть, каждая из моих гипотез имеет недостаток, и я действительноне понимаю, что именно подразумевается под этим термином в этом абзаце.