Ответ 1
Перечислители при использовании-деклараций
Проблема заключается в том, что в стандарте указано, что вы не должны ссылаться на перечислитель внутри класса enum при использовании указания использования-объявления.
7.3.3p7
Объявлениеusing
[namespace.udecl]
(n3337)Использование-объявления не должно указывать перечислитель с областью.
namespace N {
enum class E { A };
}
using N::E; // legal
using N::E::A; // ill-formed, violation of [namespace.udecl]p7
Примечание: clang
принимает обе строки выше; здесь соответствующий отчет об ошибке.
Совершенно нормально ссылаться на фактическое имя класса enum, но попытка ссылаться на один из его счетчиков плохо сформирована.
Перечислители в объявлениях псевдонимов
В стандарте указано, что объявление alias может использоваться только для обозначения имени типа, поскольку перечислитель не является типом, поскольку один в таком контексте плохо сформирован.
namespace N {
enum class E { A };
}
using x = N::E; // legal, `N::E` is a type
using y = N::E::A; // ill-formed, `N::E::A` isn't a type
Альтернативы использованию и псевдонимов-деклараций
Вы можете объявить константу с инициализацией any-name-of-your-choice со значением, которое вы хотели бы "псевдоним":
namespace N {
enum class E { A };
}
constexpr N::E x = N::E::A;
int main () {
N::E value = x; // semantically equivalent of `value = N::E::A`
}