Esta pregunta vino a mi mente, cuando tuve algo como
enum Folders {FA, FB, FC};
y quería crear una matriz de contenedores para cada carpeta:
ContainerClass*m_containers[3];
....
m_containers[FA] = ...; // etc.
(Usar mapas es mucho más elegante de usar: std::map<Folders, ContainerClass*> m_containers;
)
Pero volviendo a mi pregunta original: ¿Qué pasa si no quiero codificar el tamaño de la matriz? ¿Hay alguna manera de averiguar cuántos elementos hay en las carpetas? (Sin depender, por ejemplo, de FC
ser el último elemento de la lista que permitiría algo como ContainerClass*m_containers[FC+1]
si no me equivoco).
c++
count
enumeration
fuenfundachtzig
fuente
fuente
int(FA) | int(FB) | int (FC)
también es un valor legal para unaFolders
variable. Si está dimensionandom_containers
para que cualquierFolders
variable sea un índice válido,[FC+1]
no sería lo suficientemente grande.Respuestas:
Realmente no hay una buena manera de hacer esto, generalmente ves un elemento adicional en la enumeración, es decir
Entonces puedes hacer:
Aunque todavía no es muy agradable.
Pero, por supuesto, se da cuenta de que solo el número de elementos en una enumeración no es seguro, dado, por ejemplo,
el número de elementos sería 4, pero los valores enteros de los valores de enumeración estarían fuera del rango del índice de la matriz. El uso de valores de enumeración para la indexación de matrices no es seguro, debe considerar otras opciones.
editar: según lo solicitado, hizo que la entrada especial sobresaliera más.
fuente
Para C ++, hay varias técnicas de enumeración con seguridad de tipos disponibles, y algunas de ellas (como el Boost.Enum propuesto pero nunca enviado ) incluyen soporte para obtener el tamaño de una enumeración.
El enfoque más simple, que funciona tanto en C como en C ++, es adoptar una convención para declarar un valor ... MAX para cada uno de sus tipos de enumeración:
Editar : Con respecto a
{ FA, FB, FC, Folders_MAX = FC}
versus{FA, FB, FC, Folders_MAX]
: prefiero establecer el valor ... MAX al último valor legal de la enumeración por algunas razones:Folders_MAX
da el máximo valor de enumeración posible).Folders_MAX = FC
destaca un poco más de otras entradas (lo que hace que sea un poco más difícil agregar accidentalmente valores de enumeración sin actualizar el valor máximo, un problema al que Martin York hizo referencia).fuente
enum Folders { FA, FB, FC, Folders_MAX }; ContainerClass *m_containers[Folders_MAX];
:?struct SomeEnum { enum type {FA, FB, FC, NB__};};
¿Qué hay de los rasgos, en estilo STL? Por ejemplo:
escribe un
especialización (posiblemente constexpr si usa c ++ 11). Luego, en su código de prueba, proporcione cualquier aserción estática para mantener las restricciones que std :: numeric_limits :: max () = last_item.
fuente
std::numeric_limits<enum Foo>::max()
siempre devuelve cero ... (vea la pregunta para la respuesta vinculada) Probado en enumeraciones normales (enum Foo { ... }
), enumeracionesenum class Foo : uint8_t { ... }
con sugerencias de tipo ( ) con gcc 5.2.0 @ Linux y MinGW 4.9.3 @ Windows.std::numeric_limits<std::underlying_type<Foo>::type>::max()
, devuelve el valor máximo del tipo subyacente, es decir, 0xFFFFFFFF para enteros de 32 bits, que no es útil en este contexto.)namespace gx { enum struct DnaNucleobase : char { A, C, G, T }; }
Entonces:namespace std { template<> struct numeric_limits<enum ::gx::DnaNucleobase> { typedef enum ::gx::DnaNucleobase value_type; static constexpr value_type max() { return value_type::T; } (...)
Estd::cout << std::numeric_limits<::gx::DnaNucleobase>::max() << std::endl;
imprime el resultado esperado. Probado con sabores gcc 5.2.1 y 4.8 / 4.9.numeric_limits<T>::max()
. Lo único que esa función podría devolver razonablemente es el valor enumerado más alto. Volvería2
, pero el OP (en este caso específico) lo necesitaría para volver3
. Una vez que tenga valores no predeterminados para la enumeración (FB = 2057
), todas las apuestas están desactivadas, ni siquiera+ 1
puede esquivar el error de uno por uno. Si hubiera unnumeric_limits<T>::number_of_elements_of_the_set()
(o un nombre más corto), podría usarse sin ambigüedad.Agregue una entrada, al final de su enumeración, llamada Folders_MAX o algo similar y use este valor al inicializar sus matrices.
fuente
Me gusta usar enumeraciones como argumentos para mis funciones. Es un medio sencillo para proporcionar una lista fija de "opciones". El problema con la respuesta más votada aquí es que al usarla, un cliente puede especificar una "opción no válida". Como un derivado, recomiendo hacer esencialmente lo mismo, pero usar un int constante fuera de la enumeración para definir el recuento de ellos.
No es agradable, pero es una solución limpia si no cambia la enumeración sin actualizar la constante.
fuente
Realmente no veo ninguna forma de llegar realmente al número de valores en una enumeración en C ++. Cualquiera de las soluciones mencionadas anteriormente funciona siempre que no defina el valor de sus enumeraciones si define su valor que podría encontrarse en situaciones en las que crea matrices demasiado grandes o demasiado pequeñas
en esto sobre ejemplos, el resultado crearía una matriz de 3 elementos cuando necesite una matriz de 5 elementos
en esto sobre ejemplos, el resultado crearía una matriz de 301 elementos cuando necesite una matriz de 5 elementos
La mejor manera de resolver este problema en el caso general sería iterar a través de sus enumeraciones, pero eso no está en el estándar hasta donde yo sé
fuente