0

First english is not my first language. If you need something explained more just ask.

What I want to do, is make a class that extends the use of an enum. Say you have

enum Color 
{ red,
  green, 
  blue };

I want to make a class, so I can make an object like

CustomEnum myEnum("red", 
                  "green", 
                  "blue", 
                  "The house is red", 
                  "The tree is green", 
                  "The car is blue");

This way, I could call something like

myEnum.getString(red);

With a custom function, it would return the mapped value of "The house is red". However I have many many more functions I want to write, and have many enum's.

CustomEnum mySecondEnum("pizza", 
                  "soup", 
                  "eggs", 
                  "burger", 
                  "The pizza is hot", 
                  "The soup has gone cold", 
                  "The eggs are bad",
                  "The burger has cheese");

Notice the two enum's have different sizes, but CustomEnum does not care.

I have done lots of googling and came up with either this cannot be done (because enums are made at compile), or I am googling the wrong things. at this point I want to confirm that this cannot be done or if someone can point me in the right direction.

  • 4
    Why don't you just use a `std::map` ? – CinCout Jun 10 '16 at 06:39
  • Other dupe: [How to convert an enum type variable to a string?](http://stackoverflow.com/q/5093460/514235)... The premises of the Q has a problem. Apparently, you want to have a single `CustomEnum` and combine all the enum types like `Color`, `Food` etc into that. But how are you going to check if the `red` and `pizza` are not same. Hence for every enum type, you may require a separate `std::map`. For that you may refer the linked & above dupes. – iammilind Jun 10 '16 at 06:55

1 Answers1

1

Given your...

enum Colour { red, green, blue };

You can create a separate mapping:

std::map<Colour, std::string> colour_strings = {
    { red, "red" }, { green, "green" }, { blue, "blue" }
    // or if you like...
    { red, "The house is red" }, { green, "The tree is green" },
    { blue, "The car is blue" }
};

You can then lookup the strings in your code:

Colour my_colour = green;
std::cout << colour_strings[my_colour] << '\n';

There are a variety of "tricks" C++ developers use to make this easier, including:

#define X(NAME) { NAME, #NAME }

std::map<Colour, std::string> colour_strings = {
    X(red), X(green), X(blue)
};

...and...

colours.h

X(red)
X(green)
X(blue)

the_app.cc

// include once to create enum itself...
#define X(IDN) IDN,
enum Colours {
#include "colours.h"
    something_for_after_last_comma
};

// include again to create colour string mappings...
#define X(IDN) { IDN, #IDN }
std::map<Colour, std::string> colour_strings = {
#include "colours.h"
};
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • To be pedantic, I would either make the `color_strings` as a `const` or will not use `operator[]`. Because OP may not expect to create an empty string, when certain `enum` value is not mapped [un]knowingly. Also `Color` as a key for the `std::map` is not right, because OP expects `pizza` etc.. In case if `pizza` and `red` collide then that will invalidate the whole structure. So the question itself is with less information. – iammilind Jun 10 '16 at 06:48
  • @iammilind: making `colour_strings` `const` would prevent `operator[]` being used, so if the program can not be trusted to have valid enumerations then moving away from direct use of map to e.g. `const char* str(Colour)` is probably better anyway, and I tend to implement an `operator<<` for the `enum` type which permits lexical casting too... rapidly gets complex but I think what I've presented is reasonable for a learner asking this question. Re "`Color` as a key is not right" - the question shows "red" quoted in the `CustomEnum` but `myEnum.getString(red);` as client usage - so who knows? – Tony Delroy Jun 10 '16 at 06:58
  • Enumerations can certainly have the same value preventing their use as keys, and it's valid for an enum to take on values not matching any enumeration identifier (e.g. commonly a bitwise OR of values) - not saying this works for all enumerations. – Tony Delroy Jun 10 '16 at 06:59