3

I have the following enum and map:

typedef enum {
    MaxX = 0,
    MaxY,
    MaxCells,
    MaxCycles,
    Threes
} SettingName;

typedef std::map<SettingName, const char*> SettingNameCollection;

SettingNameCollection settingNames;

And I have the following function to return the enum name:

const char* gofBoard::getSettingName(unsigned x) {
    return settingNames[static_cast<SettingName>(x)];
}

And from what I've read that should work, but the function doesn't return anything. There's no compile time errors, and no runtime errors.

Krzaku
  • 186
  • 4
  • 16

5 Answers5

4

Here's my suggestion:

1- Write this macro:

#define SMART_STRINGIFY_CASE(ENUM_CODE) case ENUM_CODE: return # ENUM_CODE

2- Write this function:

const char* SettingNamesToString( settingNames const input)
{
  switch(input)
  {
    SMART_STRINGIFY_CASE(MaxX);
    SMART_STRINGIFY_CASE(MaxY);
    ...
  default:
    // your own ! 
}
0x26res
  • 11,925
  • 11
  • 54
  • 108
  • That seems to be the best solution (and easiest to implement for me) from all answers, that way I can get rid of the map. However the whole point of using the map was to make the code easier to maintain, so I only had to change the enum to add new settings. – Krzaku Dec 13 '12 at 10:00
  • @Krzaku: wiht the map you would have had to add the value to the map as well. I think the lowest maintenance solution is using boost with `SANDBOX_DEFINE_ENUM`, but it gives you less control – 0x26res Dec 13 '12 at 10:38
1

The operator[] is used to retreive/insert data in a std::map. You might be more conformtable with std::map::find:

const char* gofBoard::getSettingName(unsigned x) {
    auto found = settingNames.find(static_cast<SettingName>(x));
    if (found == settingNames.end())
        /* throw appropriate exception */
    /* or assert */
    assert ( found != settingNames.end() );
    return found->second;
}

EDIT: like someone said, for your purpose, a simple std::array would be enough.

phaazon
  • 1,972
  • 15
  • 21
  • OP needs a mapping between enums and a string representation of their values, so an array would not do by itself. – juanchopanza Dec 13 '12 at 07:26
  • `std::array tbl{ "MaxX", "MaxY", "MaxCells", "MaxCycles", "Threes" }`. Since an enum can be cast to int and it’s enum starts at 0 and the stride is 1, it will do it. – phaazon Dec 13 '12 at 12:38
0

If you do not populate the map before you call that function, what you are getting isnt an error, its a blank string (im guessing)

You want to do something like this

typedef std::array<const char*,Threes+1> SettingNameCollection;  
// usually for such purposes, sometimes an extra enum is added to give you number of valid enum values ( Settings_Num for instance)

SettingNameCollection settingNames {
    "MaxX ",
    .....
    "Threes",
}; // first time using the new syntax, is this correct?

const char* gofBoard::getSettingName(SettingName setting) {
    return settingNames[setting]; //do i need to cast to int in c++11?
}
Karthik T
  • 31,456
  • 5
  • 68
  • 87
0

A map is certainly overkill if your enum is contiguous. I would suggest switching to a macro definition.

Excerpt:

SANDBOX_DEFINE_ENUM(MyEnum, (Foo)(Bar)(Team))

Will expand to:

struct MyEnum {
  enum Type {
    Foo,
    Bar,
    Team
  };
  static Type const First = Foo;
  static Type const Last = Team;
};

inline char const* toString(MyEnum::Type value) {
  switch(value) {
  case MyEnum::Foo: return "Foo";
  case MyEnum::Bar: return "Bar";
  case MyEnum::Team: return "Team";
  }
  return 0;
}
Community
  • 1
  • 1
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
0

Everyone who programmed in C++ extensively has run into the problem of enum to string conversion (and string to enum conversion). There are various aspects to consider to solve the problem well, e.g. what if the string for an invalid enum is requested. I think you will benefit by using a generic solution that you can use for most or all of your enums. That problem is covered by this question:

Which Typesafe Enum in C++ Are You Using?

Community
  • 1
  • 1
Peter
  • 5,608
  • 1
  • 24
  • 43