Permettre de Gamme Pour les à énumérer les classes?
J'ai un récurrentes morceau de code où je boucle sur tous les membres d'une enum class
.
La for
boucle que j'utilise actuellement a l'air très difficile par rapport à la nouvelle range-based for
.
Est-il possible de prendre avantage de la nouvelle C++11 caractéristiques de couper vers le bas sur le niveau de verbosité pour mon for
boucle?
Code actuel que j'aimerais améliorer:
enum class COLOR
{
Blue,
Red,
Green,
Purple,
First=Blue,
Last=Purple
};
inline COLOR operator++( COLOR& x ) { return x = (COLOR)(((int)(x) + 1)); }
int main(int argc, char** argv)
{
//any way to improve the next line with range-based for?
for( COLOR c=COLOR::First; c!=COLOR::Last; ++c )
{
//do work
}
return 0;
}
En d'autres termes, il serait bien si je pouvais faire quelque chose comme:
for( const auto& c : COLOR )
{
//do work
}
- Intéressant. Ada avait cette fonction depuis 1983.
(COLOR)(((int)(x) + 1))
Au lieu deint
, pensez à utiliserstd::underlying_type<COLOR>::type
.- Est-il prévu que le Violet est ignorée?
- pour un grand bout - a essayé de
#include <type_traits>
, mais des problèmes de compilation de gcc 4.6.1 - va enquêter sur les en-têtes. std::underlying_type
est ce n'est pas pris en charge sur GCC 4.6. Il sera pris en charge sur 4.7. Il y a une évaluation approximative de l'émulation ici: stackoverflow.com/a/7932617/46642.- merci encore une fois!
- Gah! si vite à l'accepter. J'ai l'habitude d'attendre 24 heures juste pour donner à tous les fuseaux horaires une chance de trouver une meilleure réponse.
- Ce dont nous avons besoin est quelque chose comme les "valeurs de () la méthode de Java a pour ses énumérations. Cela pourrait retourner une sorte de jeu ou de la carte conteneur qui peut être itéré. Ce conteneur peut être calculée au moment de la compilation à l'aide de modèles.
- Si vous voulez un coup de pouce de la solution, voir boost.2283326.n4.nabble.com/... '[Plage][Itérateur] itérer sur une énumération? '
Vous devez vous connecter pour publier un commentaire.
Itération des énumérations à l'énumération lui-même comme un itérateur est une mauvaise idée, et je recommande l'aide d'un itérateur comme dans deft_code de réponse. Mais si c'est vraiment ce que vous voulez:
Travail ici: http://ideone.com/cyTGD8
Sur l'itérateur côté des choses, le plus simple est tout simplement:
Comme on le voit ici: http://ideone.com/9XadVt
(La déclaration séparée et defintinion de la matrice fait une erreur de compilation si le nombre de couleurs ne correspond pas au nombre d'éléments dans le tableau. Excellent facile de vérification de la sécurité.)
operator*
de faireCOLOR
un itérateur d'entrée.operator*
ressembler?class
? Probablement pas...operator++
operator++
, et il était aussi dans les liens de code, mais je vais voir si je peux résoudre la question des cheveuxstd::underlying_type
(pour déterminer le type de cast) comme James mentionne dans les commentaires au lieu de casting pourint
return First;
doit êtrereturn COLOR::First;
(et de même pour laLast
). Deuxièmement, faire en sorteend()
retourne la dernière valeur signifie que lafor
boucle ne itérer sur cette valeur; le corps de la boucle ne s'exécute que pour les 3 premiers des 4 valeurs de typeCOLOR
. Votre exemple utilise un style ancienenum
plutôt qu'unenum class
, et il définitLast
en tant que distincte de la valeur au-delà de la plus haute valeur valide, ce qui est pourquoi il fonctionne.Personnellement, je n'aime pas surcharger le
++
opérateur pour les énumérations. Souvent incrémentation une valeur d'enum n'a pas vraiment de sens. Tout ce qui est vraiment wanted est un moyen de itérateur sur l'enum.Ci-dessous est un générique
Enum
classe qui prend en charge l'itération. Il est fonctionnel, mais incomplète. Une véritable mise en œuvre ferait bien d'en restreindre l'accès par le constructeur et ajoutez tous les itérateur traits.T from_string( const string& T )
est un peu une douleur en C++, on ne peut pas la surcharge sur le retour à la valeur d'enum. Le même problème existe si oui ou non je utiliser un modèle-Enum, mais avec un modèle Enum, c'est juste un peu plus verbeux.Last
pour être plus conforme à la normale itérateur plages.Alors:
De nombreuses fois, je l'utilise comme ça, où je veux un 'none' valeur:
3
? Ne devrait-elle pas être2
? Et si oui, n'est-ce pas illustrer que violer le principe DRY conduit toujours à un dur-à-voyez des bugs?Vous pourriez probablement faire quelque chose d'intelligent avec boost::mpl, une version grossière pourrait ressembler à:
Voici une testé exemple GCC (4.6.1):
J'aime l'idée d'un lot et ont souvent souhaité pour elle.
Le problème que je vois est ce qui se passe quand il est répété valeur numérique pour un enum élément. Toutes les implémentations je vois ci-dessus nécessitent des moulages de type intégral et ++. En fin de compte, je pense que support de la langue peut être nécessaire pour vraiment faire une itération sur chaque élément dans tous les cas. Il permettrait d'éliminer la nécessité d'avoir en Premier, Dernier ou du début, Fin, bien que je n'ai pas l'objet de cette trop. C'est comme chercher begin() end() pour les conteneurs.
La numérotation commence à Mauve.
Si vous êtes une personne terrible que vous pouvez obtenir ce comportement avec le préprocesseur, quelque chose comme:
Avec des modifications mineures cela pourrait également soutenir par exemple. ENUM_SETVALUE(Bleu, 4) et de faire un const carte de eg. COULEUR::Bleu "Bleu". Et vice-versa.
Je souhaite que le standard a tout construit de ces fonctions comme des options à la classe enum. Aucune de ces solutions sont bonnes.
Je suis sûr que vous pouvez itérer sur les membres d'une C++ initializer_list, donc je pense que j'ai fait dans le passé:
Si il y a des problèmes avec cela, je ne sais pas, mais je pensais que je voudrais suggérer que c'est concis, mais pas l'idéal si il y a beaucoup de Couleurs.
Si vous approuvez ou non de l'incrémentation des enums il y a des moments où il est utile. Alors voici une façon simple de le faire:
Il n'y a pas de frais généraux puisque le compilateur va prendre soin de la coulée et de référencement. Ajouter le contrôle de la portée ou d'autres capacités nécessaires.