Cette question m'est venue à l'esprit, quand j'avais quelque chose comme
enum Folders {FA, FB, FC};
et voulait créer un tableau de conteneurs pour chaque dossier:
ContainerClass*m_containers[3];
....
m_containers[FA] = ...; // etc.
( En utilisant des cartes , il est beaucoup plus élégante à l' utilisation: std::map<Folders, ContainerClass*> m_containers;
)
Mais pour revenir à ma question initiale: que se passe-t-il si je ne souhaite pas coder en dur la taille du tableau, existe-t-il un moyen de déterminer le nombre d'éléments dans les dossiers? (Sans compter sur par exempleFC
être le dernier élément de la liste, ce qui permettrait quelque chose comme ContainerClass*m_containers[FC+1]
si je ne me trompais pas.)
c++
count
enumeration
fuenfundachtzig
la source
la source
int(FA) | int(FB) | int (FC)
est également une valeur légale pour uneFolders
variable. Si vous effectuez un dimensionnement dem_containers
sorte qu'uneFolders
variable soit un index valide,[FC+1]
ce ne serait pas assez grand.Réponses:
Il n'y a pas vraiment de bon moyen de faire cela, généralement vous voyez un élément supplémentaire dans l'énumération, c'est-à-dire
Alors vous pouvez faire:
Toujours pas très gentil.
Mais bien sûr, vous réalisez que seul le nombre d'éléments dans une énumération n'est pas sûr, étant donné par exemple
le nombre d'éléments serait de 4, mais les valeurs entières des valeurs d'énumération seraient bien en dehors de la plage d'index du tableau. L'utilisation de valeurs d'énumération pour l'indexation de tableau n'est pas sûre, vous devez envisager d'autres options.
edit: comme demandé, a fait ressortir l'entrée spéciale.
la source
Pour C ++, il existe diverses techniques d'énumération de type sécurisé disponibles, et certaines d'entre elles (comme le Boost.Enum proposé mais jamais soumis ) incluent le support pour obtenir la taille d'une énumération.
L'approche la plus simple, qui fonctionne aussi bien en C qu'en C ++, consiste à adopter une convention de déclaration d'une valeur ... MAX pour chacun de vos types enum:
Edit : Concernant
{ FA, FB, FC, Folders_MAX = FC}
versus{FA, FB, FC, Folders_MAX]
: je préfère définir la valeur ... MAX sur la dernière valeur légale de l'énumération pour plusieurs raisons:Folders_MAX
donne la valeur d'énumération maximale possible).Folders_MAX = FC
se démarquer un peu plus des autres entrées (ce qui rend un peu plus difficile d'ajouter accidentellement des valeurs d'énumération sans mettre à jour la valeur maximale, un problème auquel Martin York a fait référence).la source
enum Folders { FA, FB, FC, Folders_MAX }; ContainerClass *m_containers[Folders_MAX];
:?struct SomeEnum { enum type {FA, FB, FC, NB__};};
Qu'en est-il des traits, à la mode STL? Par exemple:
écrire un
spécialisation (éventuellement constexpr si vous utilisez c ++ 11). Ensuite, dans votre code de test, fournissez toutes les assertions statiques pour maintenir les contraintes que std :: numeric_limits :: max () = last_item.
la source
std::numeric_limits<enum Foo>::max()
retourne toujours zéro ... (voir la question pour la réponse liée) Testé sur les enums normaux (enum Foo { ... }
), les enums à indice de type (enum class Foo : uint8_t { ... }
) avec gcc 5.2.0 @ Linux et MinGW 4.9.3 @ Windows.std::numeric_limits<std::underlying_type<Foo>::type>::max()
, il renvoie la valeur maximale du type sous-jacent, c'est-à-dire 0xFFFFFFFF pour les entiers de 32 bits, ce qui n'est pas utile dans ce contexte.)namespace gx { enum struct DnaNucleobase : char { A, C, G, T }; }
Puis:namespace std { template<> struct numeric_limits<enum ::gx::DnaNucleobase> { typedef enum ::gx::DnaNucleobase value_type; static constexpr value_type max() { return value_type::T; } (...)
Etstd::cout << std::numeric_limits<::gx::DnaNucleobase>::max() << std::endl;
imprime le résultat attendu. Testé avec les saveurs gcc 5.2.1 et 4.8 / 4.9.numeric_limits<T>::max()
. La seule chose que la fonction peut raisonnablement renvoyer est la valeur énumérée la plus élevée. Il reviendrait2
, mais l'OP (dans ce cas précis) en aurait besoin pour revenir3
. Une fois que vous avez des valeurs non par défaut pour l'énumération (FB = 2057
), tous les paris sont désactivés, vous ne pouvez même+ 1
pas pirater l'erreur off-by-one. S'il y avait unnumeric_limits<T>::number_of_elements_of_the_set()
(ou un nom plus court), cela pourrait être utilisé sans ambiguïté.Ajoutez une entrée, à la fin de votre énumération, appelée Folders_MAX ou quelque chose de similaire et utilisez cette valeur lors de l'initialisation de vos tableaux.
la source
J'aime utiliser les énumérations comme arguments pour mes fonctions. C'est un moyen simple de fournir une liste fixe d '"options". Le problème avec la réponse la plus votée ici est qu'en utilisant cela, un client peut spécifier une "option invalide". En tant que spin-off, je recommande de faire essentiellement la même chose, mais d'utiliser une constante int en dehors de l'énumération pour en définir le nombre.
Ce n'est pas agréable, mais c'est une solution propre si vous ne modifiez pas l'énumération sans mettre à jour la constante.
la source
Je ne vois vraiment aucun moyen d'obtenir vraiment le nombre de valeurs dans une énumération en C ++. Toute solution de mention précédente fonctionne tant que vous ne définissez pas la valeur de vos énumérations si vous définissez une valeur que vous pourriez rencontrer dans des situations où vous créez des tableaux trop grands ou trop petits
dans cet exemple, le résultat créerait un tableau de 3 éléments lorsque vous avez besoin d'un tableau de 5 éléments
dans cet exemple, le résultat créerait un tableau de 301 éléments lorsque vous avez besoin d'un tableau de 5 éléments
La meilleure façon de résoudre ce problème dans le cas général serait de parcourir vos énumérations, mais ce n'est pas encore dans la norme pour autant que je sache
la source