6
votes

Contrôle de la visibilité des valeurs ENUM

Considérez une classe C ++ qui exporte une éveum, maintient une matrice interne sur cette enum et souhaite exporter une commande qui accepte des valeurs à partir de l'ENUM.

class foo {
public:
  enum color {
    red,
    yellow,
    green
  };
  void command(color c);
private:
  something somebody[color];
};


2 commentaires

Autant que je sache, ce que vous essayez de faire n'est pas vraiment possible. La prochaine meilleure chose qui vous vient à l'esprit consiste à maintenir votre clé de travail vraiment difficile et à écrire un commentaire très important sous l'énum.


Le compilateur ne vous aidera pas du stupide. Quelqu'un pourrait facilement écrire FOO: de la couleur (7) de toute façon.


4 Réponses :


0
votes

Une solution serait d'utiliser une carte: xxx

de cette façon, vous vous gardez enum propre et ne pas avoir besoin d'une taille de code difficile.


4 commentaires

J'ai examiné le fichier d'en-tête de carte et il apparaît à première vue pour transporter beaucoup de bagages. J'ai besoin de jeter un programme de test et de voir quel type de code est réellement généré. Je ne peux pas vivre avec une solution qui impose des centaines ou des milliers d'instructions de frais généraux pour une référence de tableau simple, et je ne devrais pas avoir à.


Compte tenu des frais généraux du nœud Carte en ce qui concerne sa mauvaise charge utile, il semble certainement trop exclu.


Bien sûr, il est plus lourd, mais je pense que le code C ++ est plus important que le code binaire. Il est préférable d'avoir un code très simple, sécurisé et de travail C ++ générant un binaire plus grand, car cela ne sera pas une douleur pour le processeur pour l'exercer. Wherease que c'est une douleur pour le programmeur de maintenir un code hacky. C'est la solution que je choisirais personnellement, mais c'est à vous de décider ^^


Malheureusement, mon domaine de discours est des systèmes embarqués limités de ressources.



3
votes

met l'énumération dans une classe de base une option? XXX

Personnellement, je ne ferais pas cela, car cela ressemble à un travail trop complexe. Je voudrais simplement interdire l'appelant à passer num_colors . TRUE, le système de type ne vérifie pas cela. Mais c'est sûrement une chose facile à vérifier pour les programmeurs humains. Pourquoi passeraient-ils num_colors ?


4 commentaires

Question suivante: Comment masquez-vous foo_enums ? Tout le monde peut utiliser foo_enums :: num_Colors ...


@ André: mettez-le dans un Détail Espace de noms et chaque programmateur SANE sait qu'ils ne devraient même pas penser à le toucher.


@Andre Quelqu'un peut dréérence un pointeur nul. Comment pouvons-nous les arrêter de le faire? S'ils ne peuvent pas lire et suivre un commentaire disant "Cette constante d'énum ne devrait être utilisée que par la classe" FOO ", alors c'est une pitié. Citant Herb Sutter: N'oubliez pas de faire la distinction entre« Protéger contre Murphy contre la protection contre les machiavelles . "


Ce que je veux, dans ce cas, est que la langue me permet de dire Enum foo {Baz, Bar, Waldo}; puis int Cruft [foo] ;. Je peux vivre avec une restriction dans la langue que celle-ci n'est autorisée que si aucune des valeurs Enum n'a d'altération de la valeur (exemple: Enum mangled_foo {Baz, bar = 43, Waldo};).



1
votes

Il y a une fine ligne entre protéger vos futurs de mainteneurs de faire des erreurs simples / faciles et essayer d'arrêter quelque chose qui devrait être manifestement faux, tel que l'utilisation de la valeur num_colors.

Dans votre cas. Je suggérerais d'affirmer l'entrée aux fonctions clés et de le laisser à cela.

Je pense que vous pouvez utiliser une classe de proxy de modèle spécialisée et static_assert S sur num_Colors pour empêcher les utilisateurs de passer Il dans vos fonctions.

J'ai tapé quelque chose qui semble fonctionner. xxx


2 commentaires

S'il y a une chose que j'ai apprise, c'est qu'attendre que les gens ne fassent pas quelque chose qui est évidemment mal est un exercice à l'imprudence. Ils le feront, garantis, à moins que vous ne les empêchez. Exemple: Nortel Networks Software Group a eu une politique écrite sans exception "Vous devez tester pour NULL avant la désirer du pointeur." Devinez ce que le codeur sans nom a fait? (Devinez qui a suivi la suivi de l'accident dur intermittent résultant?)


@John R. Strohm Je considère personnellement que Nortel exemple d'être complètement différent de cette situation. C'est facile oublier de vérifier un pointeur pour NULL (je ne discuterai pas si c'est une bonne idée ou non) mais dans mon esprit à l'aide d'une valeur énumérée num_colors est totalement différent. : Une décision explicite du codeur de l'utiliser. Passons-nous par des cerceaux pour essayer d'empêcher les gens de #define privé public ?



2
votes

Ma première pensée serait d'essayer de résoudre le problème lorsque vous la posez, mais après une réflexion, je déplacerais le fardeau de la commande : xxx

Étant donné que Enums sont des types si faibles, vous devez vérifier l'entrée quand même, car tout le monde pouvait facilement fournir des arguments de merde: xxx


solution originale: < Pré> xxx

Malheureusement, il y a beaucoup de duplication qui se passe (et je suis en fait originale dactylographié dactylography vert = IPL :: jaune; si cela n'a pas d'importance si vous ne faites pas d'importance si vous ne faites pas d'importance si vous ne faites jamais compte de < code> Impl S valeurs directement).

Sinon, il y a toujours le truc de macro: xxx

qui utilise une macro diabolique et Machines de préprocesseur obscur pour éviter le duplicaton de code. Il ne fonctionne évidemment que pour des éléments d'énumération consécutifs (il renvoie le nombre d'éléments, pas le nombre maximum).


4 commentaires

Cela semble être aussi proche que je vais arriver à ce que je veux en C ++. Cela me montre également comment résoudre la généralisation (que je m'attendais à être douloureux) de vouloir exporter des littéraux énumants mais pas nécessairement contigus. Il semble qu'il y ait des choses que le comité de conception C ++ ne comprend pas simplement.


@JOHN R. STROHM: Je suis d'accord, le Enum en C ++ est quelque peu cassé. Il y a deux concepts intégrés à une: la possibilité de spécifier simplement une énumération et la possibilité de "mapper" les valeurs aux noms. Ils sont sémantiquement différents et les jetant dans un seul concept le rendent maladroit (cela et le manque d'introspection, je ne vois pas pourquoi ils ne fournissent pas l'introspection de la compilation depuis sa liberté).


Je n'en sais pas assez sur l'introspection, la compilation ou le contraire, de commenter directement. J'observe que la fonctionnalité que je veux a été à ADA depuis la première version de la langue, libérée officiellement en 1983.


@John R. Strohm: J'aimerais que ce soit en C ++: /