Existe-t-il un moyen de vérifier en C ++ 11 si une énumération est continue ?
Il est tout à fait valide de donner des valeurs d'énumération qui ne le sont pas. Existe-t-il peut-être une fonctionnalité comme un trait de type en C ++ 14, C ++ 17 ou peut-être C ++ 20 pour vérifier si l'énumération est continue? À utiliser dans un static_assert.
Un petit exemple suit:
enum class Types_Discontinuous {
A = 10,
B = 1,
C = 100
};
enum class Types_Continuous {
A = 0,
B = 1,
C = 2
};
static_assert(SOME_TEST<Types_Discontinuous>::value, "Enum should be continuous"); // Fails
static_assert(SOME_TEST<Types_Continuous>::value, "Enum should be continuous"); // Passes
enum
. Malheureusement, j'ai un travail de jour, je ne peux donc pas essayer de l'écrire, même si je vais voter pour une réponse basée sur cette approche. Je suis sûr que quelqu'un comme @barry ou @sehe pourrait le faire.static_assert
)? Même si vous ne pouvez pas faire une "belle solution", veuillez quand même écrire une réponse car je suis très curieux de savoir comment cela pourrait être fait de manière générique.Réponses:
Pour un certain nombre de
enum
s, vous pouvez probablement vous frayer un chemin à travers cela en utilisant la bibliothèque Magic Enum . Par exemple:Notez que c'est en effet, comme le nom de la bibliothèque l'indique, "magique" - la bibliothèque fonctionne sur un certain nombre de hacks spécifiques au compilateur. En tant que tel, il ne répond pas vraiment à votre exigence de "C ++ pur", mais est probablement aussi bon que possible jusqu'à ce que nous ayons des installations de réflexion dans le langage.
la source
Cela n'est pas possible en C ++ pur, car il n'y a aucun moyen d'énumérer les valeurs d'énumération ou de découvrir le nombre de valeurs et les valeurs minimales et maximales. Mais vous pouvez essayer d'utiliser l'aide de votre compilateur pour implémenter quelque chose proche de ce que vous voulez. Par exemple, dans gcc, il est possible d'appliquer une erreur de compilation si une
switch
instruction ne gère pas toutes les valeurs d'une énumération:Évidemment, ceci est spécialisé pour une énumération donnée, mais la définition de ces fonctions peut être automatisée avec un préprocesseur.
la source
J'aimerais voir une réponse à ce sujet. J'en ai aussi eu besoin.
Malheureusement, je ne pense pas que cela soit possible en utilisant les utilitaires existants. Si vous voulez implémenter un trait de type sur cela, vous avez besoin du support de votre compilateur, donc écrire un modèle pour cela ne semble pas faisable.
J'ai déjà étendu l'énumération avec une balise spécifique pour indiquer qu'elle est contiguë et vous donne immédiatement la taille: constructeur de classe enum c ++, comment passer une valeur spécifique?
Alternativement, vous pouvez écrire votre propre trait:
Cela doit être spécialisé chaque fois que vous définissez une énumération contiguë où vous souhaitez l'utiliser. Malheureusement, cela nécessite une maintenance et une attention si l'énumération est modifiée.
la source
Toutes les énumérations sont continues. 0 est toujours autorisé; la valeur la plus élevée autorisée est l'énumérateur le plus élevé arrondi au suivant
1<<N -1
(tous les bits un), et toutes les valeurs intermédiaires sont également autorisées. ([dcl.enum] 9.7.1 / 5). Si des énumérateurs négatifs sont définis, la valeur la plus basse autorisée est définie de la même manière en arrondissant l'énumérateur le plus bas.Les énumérateurs définis dans le
enum
sont des expressions constantes avec une valeur dans la plage et le type correct, mais vous pouvez définir des constantes supplémentaires en dehors deenum
qui ont les mêmes propriétés:constexpr enum class Types_Discontinuous = static_cast<Types_Discontinuous>(2)
la source