Énumérer sur un enum en C++
En C++, Est-il possible de les énumérer sur un enum (au moment de l'exécution ou de la compilation (de préférence)) et les fonctions d'appel/de générer du code pour chaque itération?
Exemple de cas d'utilisation:
enum abc
{
start
a,
b,
c,
end
}
for each (__enum__member__ in abc)
{
function_call(__enum__member__);
}
Plausible doublons:
- Comment supposez-vous de choisir la fonction pour appeler? Pourriez-vous poster quelques pseudo-code comment supposez-vous faire? Il pourrait nous aider à vous aider.
- mise à jour pour le krill
- Pour l'exécution de regarder stackoverflow.com/questions/1292426/.... (S'il n'existait pas au moment de la compilation, votre question peut être une copie exacte d'elle.)
InformationsquelleAutor jameszhao00 | 2009-09-07
Vous devez vous connecter pour publier un commentaire.
À ajouter à @StackedCrooked réponse, vous pouvez surcharge
operator++
,operator--
etoperator*
et ont itérateur comme fonctionnalité.Nous allons tester avec quelques
<algorithm>
modèleMaintenant,
Color
est une constante itérateur bidirectionnel. Voici une classe réutilisable j'ai codé tout en le faisant manuellement ci-dessus. J'ai remarqué qu'elle pourrait fonctionner pour beaucoup plus d'énumérations, de sorte que de répéter le même code est assez fastidieuxMise en œuvre de la façon suivante.
C++ ne prévoit pas d'énumérateur de l'itération. Malgré cela, la nécessité se pose parfois pour cela. Une commune de la solution de contournement consiste à ajouter des valeurs qui marquent le début et la fin. Par exemple:
N'est possible sans un peu de travail manuel. Une grande partie du travail peut être fait par des macros, si vous êtes prêt à plonger dans cette région.
Étendre sur ce que Konrad dit, il est possible de l'idiome dans le cas de "générer du code pour chaque itération" est d'utiliser un fichier inclus pour représenter l'énumération:
mes trucs.h:
enum.h:
main.cpp:
Donc, pour ajouter un nouvel élément "qux", vous l'ajouter à mes trucs.h et écrire le
do_qux
fonction. Vous ne devez pas toucher à l'envoi du code.Bien sûr, si les valeurs de votre enum doivent être de règle spécifique de non-nombres entiers consécutifs, puis vous vous retrouvez le maintien de l'enum définition et la
ENUM_ELEMENT(foo)
... liste séparément, ce qui est pénible.Pas
Cependant, vous pouvez définir votre propre classe qui implémente le protocole enum comme caractéristiques avec des itérations. Vous souvenez peut-être un truc à partir de la pré 1.5 de Java jours, qu'on appelle le "sécurisée de type enum modèle de conception". Vous pourriez faire le C++ équivalent.
Cela semble hacky pour moi, mais peut convenir à vos besoins:
Si vous avez besoin d'une spéciale de la valeur de départ, vous pouvez en faire une constante et de le fixer dans votre enum. Je n'ai pas vérifier si cette compile, mais il devrait être proche d'être là :-). Espérons que cette aide.
Je pense que cette approche pourrait être un bon équilibre pour votre cas d'utilisation. L'utiliser si vous n'avez pas besoin de faire cela pour un tas de différents types énumérés et vous ne voulez pas avoir affaire avec le préprocesseur choses. Assurez-vous juste un commentaire et sans doute ajouter des choses à faire pour la changer plus tard pour quelque chose de mieux :-).
for
et imbriquéesswitch
sont tout à fait inutile/pas de sens puisque vous utilisez chacune des valeurs consécutives de toute façon. Juste omettre les deux et de les exécuterfoo stuff
, suivie parbar stuff
etc. directement.J'ai l'habitude de le faire comme ceci:
range
est complètement générique, et défini comme suit:Vous pouvez effectuer certaines du projet d'exécution des techniques de manière statique avec TMP.
La sortie de ce programme est:
Voir Ch 1 de Abrahams, Gurtovoy "C++ Template Métaprogrammation" pour un bon traitement de cette technique. L'avantage de cette façon de faire sur le projet d'exécution des techniques, c'est que, lorsque vous optimiser ce code, il peut inline de la statique et de la est à peu près équivalent à:
Inline function_call pour encore plus d'aide du compilateur.
Les mêmes critiques des autres énumération itération techniques s'appliquent ici. Cette technique ne fonctionne que si votre énumération des incréments en continu à partir d'un jusqu'à la fin par l'.
Amour de template, mais je vais prendre note de cela pour mon futur/d'autres personnes de l'utilisation de sorte que nous ne sommes pas perdus avec tout ce qui précède.
Enums sont pratiques pour le bien de comparer des choses connues ordonnée. Ils sont généralement utilisés codés en dur dans les fonctions pour des raisons de lisibilité à l'encontre des valeurs entières. Quelque peu similaire à l'définitions de préprocesseur, à l'exception qu'ils ne sont pas remplacés par des littéraux, mais conservés et accessibles au moment de l'exécution.
Si nous avions un enum la définition de html, les codes d'erreur et nous savions que les codes d'erreur de la 500s sont des erreurs de serveur, il peut être plus agréable de lire quelque chose comme:
que
La clé, c'est que, ils sont semblables à des tableaux! Mais sont utilisés pour cast valeurs entières.
Court exemple:
Souvent les enums sont aussi utilisés avec des char* matrices ou des tableaux de chaîne, de sorte que vous pouvez imprimer un message avec la valeur associée. Normalement, ils sont juste des tableaux avec le même ensemble de valeurs de l'enum, comme suit:
Et bien sûr, c'est même plus agréable de créer une classe générique qui s'occupe de l'itération pour les énumérations, comme les réponses ci-dessus.