Skip to main content
Code Review

Return to Question

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
added 92 characters in body
Source Link
Mikhail
  • 153
  • 1
  • 1
  • 7
Source Link
Mikhail
  • 153
  • 1
  • 1
  • 7

Map enum values

I want to map values of a enum to some other values. For instance, here I map Color to Group:

enum class Color {
 Red, Green, Blue, Cyan, Magenta, Yellow, White, Black
};
enum class Group {
 Primary, Secondary, Neutral
};

One particular interesting case is to map enum to a string (serialize), but I'm interested in the general case. I came out with three possibilities of doing this:

Group GetColorGroupMap(Color color)
{
 static const std::map<Color, Group> color2group = {
 { Color::Red, Group::Primary },
 { Color::Green, Group::Primary },
 { Color::Blue, Group::Primary },
 { Color::Cyan, Group::Secondary },
 { Color::Magenta, Group::Secondary },
 { Color::Yellow, Group::Secondary },
 { Color::White, Group::Neutral },
 { Color::Black, Group::Neutral }
 };
 // Shall I check the iterator here?
 return color2group.find(color)->second;
}
Group GetColorGroupArr(Color color)
{
 static const Group color2group[] = {
 Group::Primary, // Red
 Group::Primary, // Green
 Group::Primary, // Blue
 Group::Secondary, // Cyan
 Group::Secondary, // Magenta
 Group::Secondary, // Yellow
 Group::Neutral, // White
 Group::Neutral // Black
 };
 // Shall I check the index here?
 return color2group[size_t(color)];
}
Group GetColorGroupSwitch(Color color)
{
 switch (color)
 {
 case Color::Red: return Group::Primary;
 case Color::Green: return Group::Primary;
 case Color::Blue: return Group::Primary;
 case Color::Cyan: return Group::Secondary;
 case Color::Magenta: return Group::Secondary;
 case Color::Yellow: return Group::Secondary;
 case Color::White: return Group::Neutral;
 case Color::Black: return Group::Neutral;
 }
 
 // Shall I handle this branch here?
 throw std::logic_error("How did we get here?");
}

Questions

  1. What is the best solution among these and why? Maybe there are others?
  2. Shall I do the checks, mentioned in each function?
  3. Is there a way to make these functions robust to refactoring, e.g. when another color is added?

My thoughts

About question 1

  • GetColorGroupMap: potentially the most slow function, since it traverses std::map on each call.
  • GetColorGroupArr: the least obvious structure, since colors are not mentioned explicitly, they are deduced from array indices. Additionally, it won't work with non-sequential enums.
  • GetColorGroupSwitch: a little verbose and smells a little old-school. I do not see any particular problems with it here, though.

About question 2

I think no checks are necessary, since failures are possible only if passed Color is out of specified range, which means, something went wrong before.

About question 3

The only possibility I see is to modify GetColorGroupArr by adding static_assert to check that array size is equal to the number of items in Color. For this, we may add an extra item COUNT to Color. I do not like this approach, since we need to check against this special item in every place enum is used.

lang-cpp

AltStyle によって変換されたページ (->オリジナル) /