La technique de Faire quelque chose d'à la fois un C identifiant et un string? peut être utilisé ici.
Comme d'habitude avec ces préprocesseur choses, écrire et comprendre le préprocesseur partie peut être difficile, et inclut la transmission des macros pour les autres macros et implique l'utilisation de # et ## les opérateurs, mais son utilisation est très facile. Je trouve ce style très utile pour les longues énumérations, où le maintien de la même deux fois la liste peut être vraiment gênant.
Usine de code tapé une seule fois, généralement cachés dans l'en-tête:
enumFactory.h:
// expansion macro for enum value definition
#define ENUM_VALUE(name,assign) name assign,
// expansion macro for enum to string conversion
#define ENUM_CASE(name,assign) case name: return #name;
// expansion macro for string to enum conversion
#define ENUM_STRCMP(name,assign) if (!strcmp(str,#name)) return name;
/// declare the access function and define enum values
#define DECLARE_ENUM(EnumType,ENUM_DEF) \
enum EnumType { \
ENUM_DEF(ENUM_VALUE) \
}; \
const char *GetString(EnumType dummy); \
EnumType GetEnumValue(const char *string); \
/// define the access function names
#define DEFINE_ENUM(EnumType,ENUM_DEF) \
const char *GetString(EnumType value) \
{ \
switch(value) \
{ \
ENUM_DEF(ENUM_CASE) \
default: return ""; /* handle input error */ \
} \
} \
EnumType GetEnumValue(const char *str) \
{ \
ENUM_DEF(ENUM_STRCMP) \
return (EnumType)0; /* handle input error */ \
} \
Usine utilisé
someEnum.h:
#include "enumFactory.h"
#define SOME_ENUM(XX) \
XX(FirstValue,) \
XX(SecondValue,) \
XX(SomeOtherValue,=50) \
XX(OneMoreValue,=100) \
DECLARE_ENUM(SomeEnum,SOME_ENUM)
someEnum.cpp:
#include "someEnum.h"
DEFINE_ENUM(SomeEnum,SOME_ENUM)
La technique peut être facilement étendue pour que XX macros accepte plus d'arguments, et vous pouvez aussi avoir préparé plusieurs macros pour remplacer XX pour des besoins différents, à l'image des trois que j'ai fournis dans le présent échantillon.
Comparaison de X-Macros
Tout ceci est similaire à X-Macros d'autres l'ont mentionné, je pense que cette solution est plus élégante qu'elle ne nécessite pas de #undefing de tout, ce qui vous permet de cacher des choses compliquées est dans l'usine, le fichier d'en-tête - le fichier d'en-tête est quelque chose que vous ne sont pas de toucher à tout, quand vous avez besoin de définir un nouveau protocole enum, par conséquent, de nouvelles enum définition est beaucoup plus court et plus.