Déclarer explicitement une conversion de int => Enum

Signaler
Messages postés
185
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
16 juillet 2016
-
Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
-
Bonjour,

J'ai pas mal d'énumération dans mon programme et j'ai souvent besoin de de prendre un simple int en entrée et de le convertir en l'Enumération correspondante.

J'ai donc plein de fonction du type :
class Tool
{
public :
enum Enum
{
    Enum_default,
    Enum_1,
    ....
    Enum_n
}

static Enum toEnum(int i)
{
  switch(i)
  {
    case Enum_1: return Enum_1;break;
    ...
    default : return Enum_default;break;
  }
}
};

Donc quand je fais un truc du genre :
Enum e =  156;

J'ai l'erreur "no explicit conversion from int to Enum "
Je sais que ça, ça fonctionne :
Enum e = (int)156;
//Pas propre (si la valeur 156 n'est pas dans Enum  ???)
// Idem pour static_cast... dynamic_cast...

ça c'est ok :
Enum e = Tools::toEnum(156);


Par contre j'aimerai savoir s'il n'y aurai pas moyen de "déclarer" explicitement une conversion implicite... :o)
du genre une surcharge d'opérateur= ou une sorte d' opérateur=
Enum int(int i)...

Afin d'alléger un peu mon code et de pouvoir faire ça :
Enum e  = 156;

Sans rajouter quoi que ce soit

Merci d'avance

Hervé

L'intelligence est la chose la mieux répartie chez l'homme, car quoi qu'il en soit pourvu, il a toujours l'impression d'en avoir assez. "Descartes"

3 réponses

Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
113
Bonjour.

Remarques conceptuelles:

j'ai souvent besoin de de prendre un simple int en entrée et de le convertir en l'Enumération correspondante

Si tu as souvent besoin de l'entier et non d'en enum, il y a alors potentiellement un souci de conception, non ? La solution ne serait-elle pas d'avoir des entiers, sans enum ?

//Pas propre (si la valeur 156 n'est pas dans Enum ???)

Tu viens de te donner la réponse :) On n'est pas censé convertir un entier en enum implicitement, raison pour laquelle aucun système n'a été prévu pour cela.

Remarques techniques:

case Enum_1: return Enum_1;break;

Si tu as un return, nul besoin de break.

default : return Enum_default;break;

Le break est inutile dans un "default".

Enum e = (int)156;

Jamais de "C cast", préfère les cast C++: static_cast, reinterpret_cast, dynamic_cast, etc...

Pour répondre à ta question:
- Pourquoi as-tu besoin de cela ?
- Si tu y tiens vraiment, tu peux générer les fonctions de passage enum vers int, et inversement, via des macros. Essaie de t'inspirer de: http://www.codeproject.com/KB/cpp/C___enums_to_strings.aspx

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
185
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
16 juillet 2016

Merci pour ta réponse
C'est ce que je fais déjà, mais effectivement, je pourrai le faire avec des MACRO... ça simplifierait l'ajout de nouvelles enum...

En fait, mon programme importe des données d'une base de donnée, qui fonctionne biensûr avec ses propres types indexés via des int.
Par exemple, j'ai des champs LINESTYLE = 1,2,3... suivant qu'ils soient Solid, Dash,Dot,...
Etant donné que je veux afficher ces données, je souhaite donc convertir ces int qui représentent finalement un concept plutôt qu'une valeur, ne serait-ce que pour derrière, travailler avec des switch et avoir un code lisible.
Je pourrai aussi passer par des
#define LS_SOLID 1
#define LS_DASH 2
...

C'est une autre solution mais qui est loin d'être la meilleure selon moi et ne permet d'utiliser proprement des switch couvrant (ou non, mais dans ce cas il y facilement moyen de le savoir puisqu'il y a une message à la compilation s'il n'y a pas de "default") la totalité des cas possibles.
Derrière j'utilise Qt, j'ai deux choix, soit je convertis directement mes int en enum de Qt, soit je convertis mes int dans une Enum avec des noms collant directement à ceux de la base (lisibilité du code et maintenance), Enum que je transtyperai ensuite en Enum Qt au moment de l'affichage... de toutes les manières, je suis obligé de convertir mes int en Enum proprement, en se souvenant que les valeurs des int et différentes Enum ne sont pas forcément les mêmes.
DataBase(LINESTYLE=1) = DB_LINESTYLE::SOLID != Qt::SolidPattern... => conversion

Voilà le pourquoi, maintenant, le comment... j'espérai qu'il y ait une solution pour faire ça implicitement.. à moins de créer une classe à la place de chaque enum et de surcharger l'opérateur =(int& i)... j'ai cru voir le int(int& i) aussi...

L'intelligence est la chose la mieux répartie chez l'homme, car quoi qu'il en soit pourvu, il a toujours l'impression d'en avoir assez. "Descartes"
Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
113
Par exemple, j'ai des champs LINESTYLE = 1,2,3... suivant qu'ils soient Solid, Dash,Dot,...

Ce n'est pas très élégant ! Il y a des enums dans une bdd (je me doute que tu fais avec l'existant :p).

je souhaite donc convertir ces int qui représentent finalement un concept plutôt qu'une valeur

Dans ce cas, le seul moyen d'avoir une conversion implicite, est de ne pas avoir d'enum.
Ta solution avec le define est la bonne. Comme le define n'est pas typé, je te conseille plutôt du "static const int" (si tu peux éviter define, évite le !).

Ex:
static const int LS_SOLID = 1; // Identique à define, mais typé !
static const int LS_DASH = 2;


Voilà le pourquoi, maintenant, le comment... j'espérai qu'il y ait une solution pour faire ça implicitement.. à moins de créer une classe à la place de chaque enum et de surcharger l'opérateur=(int& i)... j'ai cru voir le int(int& i) aussi...

Ça revient au même que de créer une fonction de conversion par classe. Sauf que pour faire fonctionne une surcharge telle que tu la décris, il faut une instance de classe, et donc tu va te payer la construction inutile d'un objet juste pour convertir. Ça serait dommage :p

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question