Tengo una clase enum con dos valores, y quiero crear un método que reciba un valor y devuelva el otro. También quiero mantener la seguridad de tipo (por eso uso enum class en lugar de enums).
http://www.cplusplus.com/doc/tutorial/other_data_types/ no menciona nada sobre métodos Sin embargo, tenía la impresión de que cualquier tipo de clase puede tener métodos.
enum class/struct
?Respuestas:
No, ellos no pueden.
Puedo entender que la
enum class
parte para enumeraciones fuertemente tipadas en C ++ 11 podría parecer que implica que tambiénenum
tieneclass
rasgos, pero no es el caso. Mi conjetura es que la elección de las palabras clave se inspiró en el patrón que usamos antes de C ++ 11 para obtener enumeraciones de alcance:Sin embargo, eso es solo sintaxis. De nuevo,
enum class
no es unclass
.fuente
union
tampoco es lo que John Doe consideraría una clase . Sin embargo, pueden tener funciones miembro. Y las clases realmente no son obligatorias para las funciones de los miembros. Usando un designador comovalue
othis
, algo asíenum Size { Huge, Mega, Apocalypse; bool operator<(X rhs) const { return *this < rhs; }
(aquí también lo permite;
), puede tener tanto sentido como otras formas de funciones.Si bien la respuesta de que "no puedes" es técnicamente correcta, creo que puedes lograr el comportamiento que estás buscando usando la siguiente idea:
Me imagino que quieres escribir algo como:
Y esperabas que el código se viera así:
Pero, por supuesto, no funciona porque las enumeraciones no pueden tener métodos (y 'esto' no significa nada en el contexto anterior)
Sin embargo, si usa la idea de una clase normal que contiene una enumeración que no es de clase y una variable de miembro único que contiene un valor de ese tipo, puede acercarse mucho a la seguridad de sintaxis / comportamiento / tipo que desee. es decir:
Ahora puedes escribir:
Y el compilador evitará cosas como:
Puede agregar fácilmente métodos tales como:
y
puede ser apoyado
fuente
Concentrándose en la descripción de la pregunta en lugar del título, una posible respuesta es
fuente
Como se menciona en la otra respuesta , no. Ni siquiera
enum class
es una clase.Por lo general, la necesidad de tener métodos para obtener
enum
resultados por la razón de que no es un enumeración regular (solo incremental), sino de una definición de valores a nivel de bits para enmascarar o necesita otras operaciones de aritmética de bits:Obviamente, uno piensa en encapsular las operaciones necesarias para re / establecer un solo / grupo de bits, por ejemplo, el valor de la máscara de bits o incluso las operaciones controladas por el índice de bits serían útiles para la manipulación de un conjunto de 'banderas' de este tipo.
los c ++ 11
struct
/class
especificación solo admite un mejor alcance de los valores de enumeración para el acceso. ¡Ni mas ni menos!Las formas de salir de la restricción que no puede declarar métodos para la enumeración (clases) son usar una
std::bitset
(clase de envoltura) o un campo de bitsunion
.union
s, y tales uniones de campo de bits pueden tener métodos (¡vea aquí las restricciones!).Tengo una muestra, cómo convertir los valores de máscara de bits (como se muestra arriba) a sus índices de bits correspondientes, que se pueden usar a lo largo de
std::bitset
aquí: BitIndexConverter.hppHe encontrado esto bastante útil para mejorar la legibilidad de algunos 'bandera' basado en la decisión algoritmos
fuente
Hay una capacidad bastante compatible (§) para refactorizar una enumeración en una clase sin tener que reescribir su código, lo que significa que efectivamente puede hacer lo que estaba pidiendo sin demasiada edición.
(§) como ElementW señala en un comentario, el código dependiente de type_traits no funcionará, por ejemplo, uno no puede usar auto, etc. Puede haber alguna forma de manejar tales cosas, pero al final se está convirtiendo una enumeración en una clase, y siempre es un error subvertir C ++
las especificaciones
enum struct
yenum class
son sobre el alcance, por lo que no forman parte de esto.Su enumeración original es, por ejemplo, 'mascota' (¡esto es solo un ejemplo!).
(1) Modifica eso a, por ejemplo, petEnum (para ocultarlo de su código existente).
(2) Agrega una nueva declaración de clase debajo de ella (nombrada con la enumeración original)
(3) Ahora puede agregar los métodos de clase que desee a su clase de mascota. p.ej. un operador de cadena
Ahora puede usar, por ejemplo, std :: cout ...
fuente
pet
nombre de tipo / instancia, ya sea de plantillas,auto
odecltype
, esto rompe, ya que tienes unpetEnum
lugar.Puede que no satisfaga todas sus necesidades, pero con operadores que no son miembros aún puede divertirse mucho. Por ejemplo:
Esto permite código como
fuente