#include <iostream>
struct a {
enum LOCAL_A { A1, A2 };
};
enum class b { B1, B2 };
int foo(int input) { return input; }
int main(void) {
std::cout << foo(a::A1) << std::endl;
std::cout << foo(static_cast<int>(b::B2)) << std::endl;
}
C'est a::LOCAL_A
ce que l'énumération fortement typée essaie de réaliser, mais il y a une petite différence: les énumérations normales peuvent être converties en type entier, tandis que les énumérations fortement typées ne peuvent pas le faire sans un cast.
Alors, existe-t-il un moyen de convertir une valeur enum fortement typée en un type entier sans conversion? Si oui, comment?
la source
Comme d'autres l'ont dit, vous ne pouvez pas avoir de conversion implicite, et c'est par conception.
Si vous le souhaitez, vous pouvez éviter d'avoir à spécifier le type sous-jacent dans la distribution.
la source
Une version C ++ 14 de la réponse fournie par R. Martinho Fernandes serait:
Comme pour la réponse précédente, cela fonctionnera avec n'importe quel type d'énumération et de type sous-jacent. J'ai ajouté le
noexcept
mot - clé car il ne lèvera jamais d'exception.Mise à jour
Cela apparaît également dans Effective Modern C ++ par Scott Meyers . Voir l'article 10 (il est détaillé dans les dernières pages de l'article dans ma copie du livre).
la source
la source
Non, il n'y a pas de moyen naturel .
En fait, l'une des motivations derrière avoir fortement tapé
enum class
en C ++ 11 est d'empêcher leur conversion silencieuse versint
.la source
La raison de l'absence de conversion implicite (par conception) a été donnée dans d'autres réponses.
J'utilise personnellement unaire
operator+
pour la conversion des classes enum vers leur type sous-jacent:Ce qui donne assez peu de "surcharge de frappe":
Où j'utilise en fait une macro pour créer des énumérations et des fonctions d'opérateur en un seul coup.
la source
J'espère que cela vous aide ou aide quelqu'un d'autre
la source
un.i
c'est le "membre actif" et vous ne pouvez lire que le membre actif d'une union.static_cast
.La réponse courte est que vous ne pouvez pas, comme le soulignent les articles ci-dessus. Mais pour mon cas, je ne voulais tout simplement pas encombrer l'espace de noms mais avoir toujours des conversions implicites, alors j'ai juste fait:
Le type d'espacement de noms ajoute une couche de sécurité de type alors que je n'ai pas à convertir statiquement les valeurs d'énumération au type sous-jacent.
la source
Foo::Foo
. Les membres peuvent être accédés commeFoo::bar
etFoo::baz
et peuvent être implicitement castés (et donc pas beaucoup de sécurité de type). Il est probablement préférable d'utiliser presque toujours des classes enum, surtout si vous démarrez un nouveau projet.Cela semble impossible avec le natif
enum class
, mais vous pouvez probablement vous moquer d'unenum class
avec unclass
:Dans ce cas,
serait équivalent à:
Ceci est en grande partie équivalent à l'original
enum class
. Vous pouvez retourner directementb::B1
pour dans une fonction avec le type de retourb
. Vous pouvez faireswitch case
avec, etc.Et dans l'esprit de cet exemple, vous pouvez utiliser des modèles (éventuellement avec d'autres choses) pour généraliser et se moquer de tout objet possible défini par la
enum class
syntaxe.la source
Comme beaucoup l'ont dit, il n'y a aucun moyen de convertir automatiquement sans ajouter des frais généraux et trop de complexité, mais vous pouvez réduire un peu votre frappe et la rendre meilleure en utilisant des lambdas si certains cast seront un peu utilisés dans un scénario. Cela ajouterait un peu de surcharge de fonction, mais rendra le code plus lisible par rapport aux longues chaînes static_cast comme on peut le voir ci-dessous. Cela peut ne pas être utile à l'échelle du projet, mais uniquement à l'échelle de la classe.
la source
Le comité C ++ a fait un pas en avant (délimitation des énumérations hors de l'espace de noms global) et cinquante pas en arrière (pas de désintégration de type enum en entier). Malheureusement,
enum class
n'est tout simplement pas utilisable si vous avez besoin de la valeur de l'énumération de manière non symbolique.La meilleure solution est de ne pas l'utiliser du tout, mais de définir vous-même l'énumération en utilisant un espace de noms ou une structure. A cet effet, ils sont interchangeables. Vous devrez taper un peu plus lorsque vous vous référez au type enum lui-même, mais ce ne sera probablement pas souvent.
la source