J'utilise personnellement une énumération améliorée parce que j'ai toujours trouvé l'énumération de C++ manquante: des messages comme Type 3 - method -begin
ne sont pas très instructifs.
Pour cette façon, j'utilise une classe simple basé sur un modèle:
template <class Holder>
class Enum
{
public:
typedef typename Holder::type enum_type;
Enum(): mValue(Invalid()) {}
Enum(enum_type i): mValue(Get(i)) {}
explicit Enum(const std::string& s): mValue(Get(s)) {}
bool isValid() const { return mValue != Invalid(); }
enum_type getValue() const { return mValue->first; }
private:
typedef typename Holder::mapping_type mapping_type;
typedef typename mapping_type::const_iterator iterator;
static const mapping_type& Mapping() { static mapping_type MMap = Holder::Initialize(); return MMap; }
static iterator Invalid() { return Mapping().end(); }
static iterator Get(enum_type i) { // search }
static iterator Get(const std::string& s) { // search }
iterator mValue;
};
Vous définissez Holder
comme ceci:
struct Example
{
typedef enum {
Value1,
Value2,
Value3
} type;
typedef std::vector< std::pair< type, std::string > > mapping_type;
static mapping_type Initialize() {
return builder<mapping_type>()(Value1,"Value1")(Value2,"Value2")(Value3,"Value3");
}
};
Vous pouvez définir une macro pour elle:
DEFINE_ENUM(Example, (Value1)(Value2)(Value3))
Mais je laisse la mise en œuvre comme un exercice (Boost.Preprocessor
est votre ami).
La chose cool est de l'utiliser!
int main(int argc, char* argv[])
{
std::string s;
std::cin >> s;
Enum<Example> e(s);
switch(e.getValue())
{
case Example::Value1:
case Example::Value2:
++e;
case Example::Value3:
std::cout << e << std::endl;
default:
}
}
La fabrique doit toujours construire l'objet correct en fonction de la chaîne. Il faut faire ifs/switches – amitlicht
Il est possible d'avoir une fonction de carte -> creator qui est bien meilleure que ifs/switches. –
Je pense que la commutation Enum est inévitable. Vous le ferez de toute façon, explicitement ou implicitement. – abatishchev