type name example enum c++ c++11 enums alias language-lawyer

c++ - name - ¿Es posible alias un enumerador de enum-class?



enum type c++ example (2)

Dada una clase de enumeración de C ++ 11, anidada dentro de varios espacios de nombres con nombres largos y feos:

namespace long_and_ugly { enum class colour { red, green, blue }; }

¿Se pueden hacer alias de los valores de enumeración? Con clang ++ 3.5, es posible hacer lo siguiente:

using long_and_ugly::colour; // take all the values into the current namespace using long_and_ugly::colour::red; // take only ''red'' into the current namespace function_taking_colour_argument( red ); // instead of fully referring to the value

g ++ 4.9, sin embargo, se queja. No puedo copiar su mensaje de error porque no puedo acceder al código, pero se quejó explícitamente del uso de la directiva o declaración de uso. También he intentado esto:

using red = long_and_ugly::colour::red;

Pero también falló. Lo siento por no pegar los errores. Sin embargo, creo que deberías poder reproducirlo.

Pregunta (s)

  • ¿Es posible declarar alias a los valores de enumeración en el estándar C ++ 11, o estaba usando una extensión de Clang?

  • Si es así, ¿cuál es la sintaxis correcta?


Enumeradores en declaraciones de uso.

El problema es que la norma dice que no debe referirse a un enumerador dentro de una clase de enumeración al usar una declaración de uso .

7.3.3p7 La declaración de using [namespace.udecl] ( n3337 )

Una declaración de uso no nombrará un enumerador de ámbito.

namespace N { enum class E { A }; } using N::E; // legal using N::E::A; // ill-formed, violation of [namespace.udecl]p7

Nota : clang acepta las dos líneas de arriba; Aquí hay un informe de error relevante .

Está perfectamente bien referirse al nombre real de la clase enum , pero tratar de referirse a uno de sus enumeradores está mal formado.

Enumeradores en alias-declaraciones.

El estándar dice que una declaración de alias solo se puede usar para referirse a un nombre de tipo , ya que un enumerador no es un tipo, usar uno en dicho contexto está mal formado.

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

Alternativas a las declaraciones de uso y alias

Podría declarar una constante con el nombre de su elección inicializado con el valor que desea "alias":

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` }


Tipo de

namespace long_and_ugly { enum class colour { red, green, blue }; } const colour red = long_and_ugly::colour::red;