Это одна из тех хитрых частей, как выполняется поиск имени.
В C ++ существует две области идентификаторов, одна для типов классов и общая область идентификаторов. Значение перечисления BAD находится в области общих идентификаторов, в то время как тип класса BAR находится в области идентификаторов классов. По этой причине вам разрешено иметь как перечислимое значение, так и класс с одинаковым именем: оба имени не конфликтуют.
Внутри класса BAD правила поиска идентификаторов найдут класс BAD до того, как он найдет перечисление, и, следовательно, ошибку. Теперь, если вы полностью определите идентификатор, тогда поиск имени сначала проверит область глобального идентификатора и сопоставит значение перечисления. С другой стороны, вам нужно будет добавить ключевое слово struct
или class
, чтобы объявить переменные типа BAD.
namespace foo {
enum bad { BAD; };
class BAD {
void worse() { bad b = ::foo::BAD; } // fully qualified will match the enum
};
}
int main() {
// foo::BAD b; // error, foo::BAD is an enum, not a type
class foo::BAD b; // correct
}
Теперь я бы посоветовал против этого использования. Как правило, не рекомендуется повторно использовать такой идентификатор. Код будет более сложным и, вероятно, вводящим в заблуждение для случайного читателя (один и тот же неквалифицированный идентификатор относится к разным вещам при использовании в разных контекстах). Если имена должны быть BAD
, рассмотрите возможность использования вмещающего пространства имен или класса либо для класса, либо для перечисления (предпочитайте перечисление там).