Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Uso de enum class. Consejos

Estas en el tema de Uso de enum class. Consejos en el foro de C/C++ en Foros del Web. Hola: Me disponía a ensayar con los nuevos tipos enumerados, pero me han entrado dos dudas. 1.- Esta está relacionada con los enum en general, ...
  #1 (permalink)  
Antiguo 14/04/2015, 02:16
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 6 meses
Puntos: 10
Uso de enum class. Consejos

Hola:

Me disponía a ensayar con los nuevos tipos enumerados, pero me han entrado dos dudas.

1.- Esta está relacionada con los enum en general, no con los "nuevos" enum

Si me creo un archivo externo sólo para definir tipos enumerados, y que tengan acceso a ellos otras clases, lo hago así:

Código C++:
Ver original
  1. namespace tipoColumna
  2. {
  3.     enum  {COLUMNA1, COLUMNA2,COLUMNA3,COLUMNA4};
  4. }

Definirlos de forma "anónima" es cómodo para hacer uso de ellos, puesto que en otras partes del código me refiero a ellos como:
Código C++:
Ver original
  1. if (indice.column()==tipoColumna::COLUMNA2)
  2.     {
  3.         --------------------
  4.     }

Pero no sé si es buena práctica o no.

Y la otra duda:

2.-Si intento hacer lo mismo con los nuevos tipos enumerados, ya no hay una conversión implícita entre el número y el enumerado. Entonces....¿es posible usar los nuevos tipos enumerados en funciones que aceptan un int como parámetro?
Por ejemplo, el método:
Código C++:
Ver original
  1. void setItemDelegateForColumn(int column, QAbstractItemDelegate * delegate)
no aceptará un enum "de los nuevos", entiendo yo. Por lo que no es este el uso de los nuevos enum (enum class). Pero no sé si estoy equivocado o no.

Saludos y gracias
__________________
Mi calculadora en Qt
  #2 (permalink)  
Antiguo 14/04/2015, 03:05
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Uso de enum class. Consejos

Cita:
Iniciado por dehm Ver Mensaje
Pero no sé si es buena práctica o no.
Los enum class se crearon principalmente para evitar "enums planos", es decir. Si tu tienes un enum tal que:

Código C++:
Ver original
  1. enum Color
  2. {
  3.   Black,
  4.   White
  5. };

Su uso acaba quedando así:

Código C++:
Ver original
  1. Color color = Black;

De tal forma que "Black" puede ser un valor definido en el enum, #define, una variable de tipo int, ... vamos, que una línea de ese tipo no te garantiza que "Black" sea un valor definido en ese enum. Incluso si en algún sitio te encuentras algo tal que:

Código C++:
Ver original
  1. int color = Black;

Puedes asumir erróneamente que "Black" lo está cogiendo del enum... cuando lo que puede suceder es que este valor venga de un #define:

Código C++:
Ver original
  1. #include <iostream>
  2.  
  3. enum Color
  4. {
  5.   Black,
  6.   White
  7. };
  8.  
  9. #define Black 100
  10.  
  11. int main( )
  12. {
  13.   std::cout << "-" << Black << "-" << std::endl;
  14. }

Sin embargo, con los enum class la cosa cambia:

Código C++:
Ver original
  1. #include <iostream>
  2.  
  3. enum class Color
  4. {
  5.   Black,
  6.   White
  7. };
  8.  
  9. #define Black 100 // <<-- Error de compilación
  10.  
  11. int main( )
  12. {
  13.   std::cout << "-" << Color::Black << "-" << std::endl;
  14. }

Incluso, aunque no se produjese el error de compilación, ahora sí queda claro que "Black" es un valor definido en el enum. Y esto será así independientemente de dónde te encuentres el uso de "Color::Black".

Así que bueno, visto lo visto yo te recomiendo usar "enum class" o, en su defecto, evitar en la medida de lo posible los "enum planos". Por cierto, una forma usada para evitar "enums planos" antes de "enum class" es la siguiente:

Código C++:
Ver original
  1. struct Color
  2. {
  3.   enum Type
  4.   {
  5.     Black,
  6.     White
  7.   };
  8. }
  9.  
  10. int main( )
  11. {
  12.   Color::Type color = Color::Black;
  13.   std::cout << "-" << color << "-" << std::endl;
  14. }

Cita:
Iniciado por dehm Ver Mensaje
2.-Si intento hacer lo mismo con los nuevos tipos enumerados, ya no hay una conversión implícita entre el número y el enumerado. Entonces....¿es posible usar los nuevos tipos enumerados en funciones que aceptan un int como parámetro?
Que no haya una conversión implícita no quiere decir que no exista una conversión explícita:

Código C++:
Ver original
  1. #include <iostream>
  2.  
  3. enum class Color
  4. {
  5.   Black,
  6.   White
  7. };
  8.  
  9. int main( )
  10. {
  11.   std::cout << "-" << static_cast<int>(Color::White) << "-" << std::endl;
  12. }

Así mismo, que una variable esté definda como "enum class" no le impide tener valores no válidos:

Código C++:
Ver original
  1. #include <iostream>
  2.  
  3. enum class Color
  4. {
  5.   Black, // 0
  6.   White  // 1
  7. };
  8.  
  9. int main( )
  10. {
  11.   Color color = static_cast<Color>( 23 );
  12.   std::cout << "-" << static_cast<int>(color) << "-" << std::endl;
  13. }

Así, en el ejemplo que has puesto, una posible solución seria forzar un cast a int.

Un saludo.
  #3 (permalink)  
Antiguo 14/04/2015, 09:43
lareto
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Uso de enum class. Consejos

Hola; puedes usar la misma forma de llamada para los dos tipos de enum. Te paso un ejemplo:

Código C++:
Ver original
  1. #include <iostream>
  2.  
  3. enum X {a = 1, b};
  4.  
  5. enum class tipoColumna {
  6.     COLUMNA1 = 100,
  7.     COLUMNA2,
  8.     COLUMNA3,
  9.     COLUMNA4 };
  10.  
  11. template<typename T>
  12. int int_enum_como_int(T t)
  13. {
  14.     return static_cast<typename std::underlying_type<T>::type>(t);
  15. }
  16.  
  17. void f(int i)
  18. {
  19.     std::cout << i << '\n';
  20. }
  21.  
  22. int main()
  23. {
  24.     f(int_enum_como_int(tipoColumna::COLUMNA1));
  25.     f(int_enum_como_int(a));
  26. }

Etiquetas: class, consejos, enum, funcion, int
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 23:25.