Dans ma classe, j'ai défini une énumération comme celle-ci:
class myClass
{
public:
enum access {
forL,
forM,
forA
};
typedef access AccessType;
AccessType aType;
};
Plus tard dans la définition d'un objet comme ceci:
myClass ob;
ob->aType = 0;
Cependant, j'obtiens cette erreur:
erreur: conversion non valide de 'int' à 'myClass :: AccessType {aka myClass :: access}' [-fpermissive]
Les champs énumérés ne correspondent-ils pas à des nombres entiers?
Non, ils sont stockés sous forme d'entiers mais ce sont des types distincts (par exemple, vous pouvez même surcharger en fonction du type enum). Vous devez convertir explicitement:
myClass ob;
ob->aType = (myClass::AccessType)0;
ou encore mieux écrire la valeur nommée correspondante de l'énum:
myClass ob;
ob->aType = myClass::forL;
Ou peut-être si vous voulez utiliser l'énum comme un ensemble de constantes de nombre entier, changez le type du champ:
class myClass
{
public:
enum {
forL,
forM,
forA
};
int aType; // just stores numbers
};
La conversion d'enum en int est implicite.
Les membres d'énumération sont sauvegardés par des valeurs entières, mais il n'y a pas de conversion implicit d'un type entier en un type énuméré. Vous devez utiliser un casting explicite si vous voulez vraiment l'écrire comme ceci:
ob->aType = static_cast<myClass::access>(0);
Vous ne pouvez pas faire de transtypage implicite à partir de int -> enum, car au moment de la compilation, il n’ya aucun moyen de savoir que le transtypage est valide.
Vous pouvez effectuez des conversions implicites dans l’autre sens, vous pouvez donc (si vous le souhaitez):
int foo = forL;
Je viens d'avoir le même problème. Je dois initialiser un objet à partir de ce que j'ai lu dans un fichier XML et, bien sûr, je n'ai aucun contrôle sur ce qui pourrait arriver à ce fichier.
Le constructeur a une énumération comme argument:
enum status_t { NOT_STARTED, STARTED, DONE };
MyObject::MyObject(int id, status_t status) : m_id(id), m_status(status){}
Donc, lors de l'analyse du fichier XML, je dois le lancer. J'ai alors préféré gérer le transtypage dans le constructeur afin que les autres classes n'aient pas à savoir quel est l'énum valide.
MyObject::MyObject(int id, int status) : m_id(id){
m_status = status_t(status);
}
Mais aucun moyen de s’assurer que la valeur provenant de XML sera dans la plage correcte.
Voici la solution que je suis venu avec:
MyObject::MyObject(int id, int status) : m_id(id){
switch(status){
case NOT_STARTED:
case STARTED:
case DONE:
m_status=status_t(status);
break;
default:
m_status=NOT_STARTED;
break;
}
}
Ceci est un choix d'implémentation, pour forcer une valeur par défaut en cas de données non cohérentes. On pourrait préférer renvoyer une exception, dans mon cas, cela se fera de cette façon.