2017-09-26 1 views
0

J'ai cherché mais je n'ai trouvé aucune solution à ce problème. J'ai un ENUM qui ne commence pas par « 0 » et d'autres valeurs sont pas non plus en séquence qui est comme,Comment obtenir l'index de la valeur dans Enum en C/C++

typedef enum{ 
a = 8, 
b = 100, 
c, 
d = 1, 
e = 9 
}numberEnum; 

Je veux obtenir l'index d'un élément dans ENUM comme celui-ci;

int myIndex = getIndex(a); // myIndex = 0 
int myIndex1 = getIndex(d); // myIndex1 = 3 
int myIndex2 = getIndex(b); // myIndex2 = 1 

int getIndex(numberEnum e) 
{ 
    // some code here 

    return index; 
} 

Je ne devrais pas utiliser Array pour cette situation. Utiliser enum est un must. Y'a-t-il une quelconque façon de réussir cela? Merci pour votre aide.

+3

Il n'y a aucun moyen direct de le faire. Mais quel est le but ici? Cherchez-vous à utiliser cette information à la compilation? –

+2

On ne peut pas faire grand-chose ici. Vous pouvez soit maintenir une liste séparée d'indices d'énumérateur (peut-être 'std :: map ', en supposant C++), soit utiliser des macros x (ou booster le préprocesseur) pour générer automatiquement cette liste. Le faire sans tableaux est stupide, mais vous pouvez générer un 'switch' avec x-macro ou quelque chose de similaire. – HolyBlackCat

+4

C ou C++? Ce n'est pas le même langage, et la solution sera différente. – Barmar

Répondre

3

Les énumérateurs n'ont pas de "valeur d'index". Donc ce n'est pas quelque chose que vous pouvez interroger, et ce n'est pas quelque chose que vous êtes censé pouvoir faire. Ces deux énumérations sont fonctionnellement équivalents:

enum alpha { first, second }; 
enum beta { second = 1, first = 0 }; 

Je suis sûr que vous pouvez faire des choses macro pour générer un mappage de tableau à partir des noms de recenseur à l'ordre dans lequel ils sont répertoriés dans l'énumération. Mais cela nécessiterait d'encapsuler l'énumération et ses énumérateurs dans les macros.

2

Vous devez faire cette association manuellement, comme ceci:

int getIndex(numberEnum e) 
{ 
    switch(e) 
    { 
     case a: 
      return 0; 
     case b: 
      return 1; 
     default: 
      return -1; 
    } 
} 
+0

Si l'exigence est que vous ne pouvez pas stocker la commande dans un tableau, c'est une alternative. – drescherjm

1

Il n'y a pas de sens sémantique pour « l'indexation d'un ENUM », ce n'est pas une structure de données ou d'un tableau, mais plutôt un type de données, il n'y a pas l'ordre, parce que la taille de l'enum est la taille d'une seule valeur - "index" n'a aucune signification. C'est une ligne demandant comment indexer un entier; c'est tout un enum est, un entier avec un sous-ensemble défini si des valeurs valides.

Vous pouvez peut-être obtenir ce que vous voulez (bien que la raison de le faire me échappe) à l'aide d'un tableau const de valeurs et en utilisant l'ENUM pour indexer:

static const int values[] = {8, 100, 101, 1, 9} ; 
typedef enum { a, b, c, d, e } numberEnum ; 

numberEnum myIndex = a ; // myIndex = 0 
numberEnum myIndex1 = d; // myIndex1 = 3 
numberEnum myIndex2 = b; // myIndex2 = 1 

int myValue = values[myIndex] ; 
int mValue1 = values[myIndex1] ; 
int mValue2 = values[myIndex2] ; 

int valueC = values[c] ; 
+0

Maintenant, c'est logique. – drescherjm

0

si vous êtes vraiment intéressé par un vilain solution à l'aide tamplates:

#include <iostream> 
#define MAPENUM(x,y) template<> struct EV<x> { static const int value=y; }; 

typedef enum{ 
a = 8, 
b = 100, 
c, 
d = 1, 
e = 9 
}numberEnum; 

template<numberEnum> struct EV { static const int value=-1; }; 

MAPENUM(a,1) MAPENUM(b,2) MAPENUM(c,3) MAPENUM(d,4) MAPENUM(e,5) 

template<numberEnum n> 
int getIndex() { 
    return EV<n>::value; 
} 

int main() { 
    std::cout << getIndex<b>() <<std::endl; 
    std::cout << getIndex<e>() <<std::endl; 
    std::cout << getIndex<d>() <<std::endl; 
    return 0; 
} 

live example