J'ai une classe enum avec deux valeurs et je veux créer une méthode qui reçoit une valeur et renvoie l'autre. Je veux également maintenir la sécurité des types (c'est pourquoi j'utilise enum class au lieu d'enums).
http://www.cplusplus.com/doc/tutorial/other_data_types/ ne mentionne rien sur les méthodes Cependant, j'avais l'impression que tout type de classe peut avoir des méthodes.
enum class/struct
confirmées?Réponses:
Non, ils ne peuvent pas.
Je peux comprendre que la
enum class
partie pour les énumérations fortement typés en C ++ 11 peut sembler impliquer que votreenum
a desclass
traits aussi, mais ce n'est pas le cas. Ma supposition éclairée est que le choix des mots-clés a été inspiré par le modèle que nous avons utilisé avant C ++ 11 pour obtenir des énumérations de portée:Cependant, ce n'est que de la syntaxe. Encore une fois, ce
enum class
n'est pas unclass
.la source
union
n'est pas non plus ce que John Doe considérerait comme une classe . Pourtant, ils peuvent avoir des fonctions de membre. Et les classes ne sont vraiment pas obligatoires pour les fonctions membres. En utilisant un désignateur commevalue
outhis
, quelque chose commeenum Size { Huge, Mega, Apocalypse; bool operator<(X rhs) const { return *this < rhs; }
(ici aussi permettant;
), cela peut avoir autant de sens que d'autres formes de fonctions.Bien que la réponse "vous ne pouvez pas" soit techniquement correcte, je pense que vous pourrez peut-être obtenir le comportement que vous recherchez en utilisant l'idée suivante:
J'imagine que vous voulez écrire quelque chose comme:
Et vous espériez que le code ressemble à ceci:
Mais bien sûr, cela ne fonctionne pas, car les énumérations ne peuvent pas avoir de méthodes (et `` ceci '' ne veut rien dire dans le contexte ci-dessus)
Cependant, si vous utilisez l'idée d'une classe normale contenant une énumération non-classe et une variable membre unique qui contient une valeur de ce type, vous pouvez vous rapprocher extrêmement de la sécurité de syntaxe / comportement / type souhaitée. c'est à dire:
Vous pouvez maintenant écrire:
Et le compilateur empêchera des choses comme:
Vous pouvez facilement ajouter des méthodes telles que:
et
peut être pris en charge.
la source
En se concentrant sur la description de la question au lieu du titre, une réponse possible est
la source
Comme mentionné dans l' autre réponse , non. Ce
enum class
n'est même pas une classe.Habituellement, le besoin d'avoir des méthodes pour un
enum
résulte de la raison pour laquelle ce n'est pas une énumération régulière (juste incrémentée), mais une sorte de définition au niveau du bit des valeurs à masquer ou qui nécessite d'autres opérations arithmétiques de bits:Évidemment, on pense à encapsuler les opérations nécessaires pour réinitialiser un seul / groupe de bits, par exemple par la valeur du masque de bits ou même des opérations pilotées par index de bits serait utile pour la manipulation d'un tel ensemble de «drapeaux».
le c ++ 11
struct
Laclass
spécification / prend simplement en charge une meilleure portée des valeurs d'énumération pour l'accès. Ni plus ni moins!Les moyens de sortir de la restriction que vous ne pouvez pas déclarer de méthodes pour enum (classes) sont, soit d'utiliser une
std::bitset
(classe wrapper), soit un champ de bitsunion
.union
s, et de telles unions de champs de bits peuvent avoir des méthodes (voir ici pour les restrictions!).J'ai un exemple, comment convertir les valeurs de masque de bits (comme indiqué ci-dessus) en leurs indices de bits correspondants, qui peuvent être utilisés
std::bitset
ici: BitIndexConverter.hppJ'ai trouvé cela assez utile pour améliorer la lisibilité de certaines décisions de `` drapeau '' basées algorithmes.
la source
Il existe une capacité assez compatible (§) pour refactoriser une énumération dans une classe sans avoir à réécrire votre code, ce qui signifie que vous pouvez effectivement faire ce que vous demandez sans trop de modifications.
(§) comme ElementW le souligne dans un commentaire, le code dépendant de type_traits ne fonctionnera pas, donc par exemple on ne peut pas utiliser auto, etc. Il peut y avoir un moyen de gérer ce genre de choses, mais à la fin, on convertit une énumération en classe, et c'est toujours une erreur de subvertir C ++
les spécifications
enum struct
etenum class
concernent la portée, donc ne font pas partie de cela.Votre énumération d'origine est par exemple "animal de compagnie" (ceci n'est qu'à titre d'exemple!).
(1) Vous modifiez cela en par exemple petEnum (afin de le cacher de votre code existant).
(2) Vous ajoutez une nouvelle déclaration de classe en dessous (nommée avec l'énumération d'origine)
(3) Vous pouvez maintenant ajouter les méthodes de classe que vous aimez à votre classe familière. par exemple. un opérateur de chaîne
Vous pouvez maintenant utiliser par exemple std :: cout ...
la source
pet
nom de type / une instance, qu'il s'agisse de modèlesauto
, oudecltype
, cela casse, lorsque vous obtenez un à lapetEnum
place.Il ne répond peut-être pas à tous vos besoins, mais avec des opérateurs non membres, vous pouvez toujours vous amuser beaucoup. Par exemple:
Cela permet du code comme
la source