Не используйте operator ++
! Что вы должны делать, если у вас есть перечисление как это ?:
enum class other_enum : int
{
low = -3000,
fabada_asturiana = 0xfabada,
answer_to_life_universe_everything = 0b101010,
high = -low
};
Как вы можете видеть, значения не достижимы увеличения одной предыдущей и даже не имеют рисунок; вместо этого используйте итераторы. На основе this answer:
// Shortcut to the enum map.
template <typename ENUM>
using enum_map = std::map<ENUM, const std::string>;
// The enum map.
template <typename ENUM>
enum_map<ENUM> enum_values{};
// Empty function to end the recursion.
void initialize() {}
// Initialize the enum map.
template <typename ENUM, typename ... args>
void initialize(const ENUM value, const char *name, args ... tail)
{
enum_values<ENUM>.emplace(value, name);
initialize(tail ...);
}
// Obtain the begin iterator to the enum
template <class ENUM, class = std::enable_if_t<std::is_enum<ENUM>{}>>
auto begin(ENUM &)
{
return enum_values<ENUM>.begin();
}
// Obtain the end iterator to the enum
template <class ENUM, class = std::enable_if_t<std::is_enum<ENUM>{}>>
auto end(ENUM &)
{
return enum_values<ENUM>.end();
}
Код выше позволяет пользователю создать карту со значениями перечислений и строки описания, он может быть использован как это:
int main()
{
initialize
(
white, "White",
red, "Red",
green, "Green",
blue, "Blue",
topleft, "Top Left",
topright, "Top Right",
bottomleft, "Bottom Left",
bottomright, "Bottom Right",
other_enum::low, "Lowest value",
other_enum::fabada_asturiana, "Typical Spanish",
other_enum::answer_to_life_universe_everything, "42",
other_enum::high, "Higher value"
);
...
return 0;
}
Но initialize
вызов является обязательным чтобы все это работало; не требуется, чтобы все перечислить в один вызов.
При всем коде выше, мы можем перебирать перечислений таким образом (Live demo):
for (const auto &v : colors{})
std::cout << v.first << '\n'; // Print values
for (const auto &v : corners{})
std::cout << v.second << '\n'; // Print names
for (const auto &v : other_enum{})
std::cout << (int)v.first << " = " << v.second << '\n'; // Print values & names
При таком подходе вы можете избежать наследования и работать с типами напрямую. Если вам нужно сохранить заказ членов перечисления, вы можете изменить enum_map
на контейнер, который сохраняет заказ, или если вам не нужно связывать значение со строкой, базовый контейнер можно изменить на вектор или список.
Нужно ли вам наследование класса? Не можете ли вы определить оператора вне класса? – thorsan
Проблема будет заключаться в определении количества элементов в перечислении, пропущенных значений и т. Д. Вы не можете увеличить число переходов в стиле C. – JvO