Как известно,
enum UnscopedColor { red, green, blue };
не только определяет тип UnscopedColor
, но и добавляет три идентификатора red
, green
и blue
в глобальную область видимости.
Это означает, что в коде мы можем написать red
и ожидать, что получим значение именно идентификатора red
из перечисления UnscopedColor
(т.е. 0). Правда ровно до тех пор, пока кто-нибудь не добавит в локальную область видимости новый идентификатор red
, который перекроет red
из глобальной области видимости. Есть много способов это сделать.
Например просто создать переменную с именем red
:
#include <iostream>
enum UnscopedColor { red, green, blue };
int main() {
std::cout << red << std::endl; // это red = 0 из UnscopedColor
auto red = 42;
std::cout << red << std::endl; // а это наша новая локальная переменная red = 42
}
Или вытащить идентификатор red
из каких-то глубин:
#include <iostream>
enum UnscopedColor { red, green, blue };
namespace A {
namespace B {
constexpr const char red[] = "red";
}
}
int main() {
std::cout << red << std::endl; // это red = 0 из UnscopedColor
using A::B::red;
std::cout << red << std::endl; // угадай кто здесь
}
В целом это достаточно универсальный механизм в C++ когда более новые идентификаторы вводятся в локальную область видимости и перекрывают старые (пока область видимости не закончится).
Тем не менее есть способ (не всегда, но есть) достучаться да скрытых идентификаторов. Например тех, которые объявлены в глобальной области видимости. Достаточно использовать префикс ::
. Т.е. в наших примерах мы можем писать ::red
и быть уверенными, что это будет именно идентификатор из UnscopedColor
, а не откуда-то еще.
Возвращаясь к оригинальному коду,
enum UnscopedColor { red, green, blue };
enum class ScopedColor { red, green, blue };
int main() {
using enum ScopedColor;
}
думаю уже стало понятно какой enum "будет использоваться". Хотя это не совсем корректный вопрос. Т.к. using enum
ничего не делает с самим типом ScopedColor
, а только вносит имена red
, green
и blue
типа ScopedColor
в локальную область видимости (и естественно перекрывает старые идентификаторы из UnscopedColor
). И если бы в ScopedColor
отсутствовал blue
, то в локальной области видимости мы бы получили прекрасный микс: red
и green
были бы типа ScopedColor
, а blue
принадлежал бы UnscopedColor
. Ну лучше так не делать разумеется.