c++enumsrangerange-based-loop

Range of enums in C++


I'm confused with range of enums. I have code like this:

namespace regs {
enum Control_0 {
    THING1,
    THING2,
    THING3
};
enum Control_1 {
    THING100,
    THING200,
    THING300
};
const auto regs_range = {Control_0, Control_1}; //error
} // regs namespace

and need to itterate over this enums like range-based for:

for (const auto& reg : regs::regs_range) {
    get_register_data(reg);
}

I also need to save feature of acces of enum values like getThingData(Control_0::THING1)

Is it possible to implement this somehow?

For itterating over values in enum I've always used this : const auto regs_values_range = {Control_0::THING1, Control_0::THING2, Control_0::THING3}; but in relation to range of enums it's error.


Solution

  • This line:

    const auto regs_range = {Control_0, Control_1};
    

    Attempts to create a collection of types (Control_0 and Control_1), not values.
    This is invalid.
    Also note that Control_0 and Control_1 are distinct and unrelated types and so you cannot put values from them in a trivial way in one collection.

    The proper solution depends on what you actually need to achieve:

    1. If you need to represent a value that can be either one of the entries from Control_0 or the entries from Control_1, you can use std::variant:

      std::variant<Control_0, Control_1>
      
    2. If on the other hand you would like to represent a value which is a pair - one entry from Control_0 together with one entry from Control_1, you can use one of the following:
      (1) std::tuple:

      std::tuple<Control_0, Control_1>
      

      (2) std::pair

      std::pair<Control_0, Control_1>
      

      (3) Create your own type holding one of each:

      struct Control_0_1
      {
          Control_0 ctrl0;
          Control_1 ctrl1;
      };
      

      IMHO option (3) is the best in this case as it will make your code clearer.

    Finally you can store any of the above in a container (e.g. std::vector or any other) and iterate over them.