Search code examples
c++enumsargumentspass-by-referencepass-by-value

Returning enums by value or reference in C++ and possibility of subset of enums


Consider following scenario:

I need to process fruits which most of the time I get in combinations [but not always, lets assume] so I created enum as shown below :

enum class ProcessInputFruits {None, Apples, Mangoes, PineApples, Grapes, GrapesAndMangoes, ApplesAndPineApples, All};

In my function ProcessFruits I am passing this enum as argument but at the same time I want to return the type of the fruit that has been processed. [It always processes only one type even when given a combination.. lets say]

Since I need to return only single type so I have created another enum containing ProcessedOutFruit.

enum class ProcessedOutFruit {None, Apples, Mangoes, PineApples, Grapes};

This is my function :

ProcessFruits(ProcessInputFruits& inputFruits, ProcessedOutFruit& outputFruits) {
     if(inputFruits == ProcessInputFruits::GrapesAndMangoes || 
            inputFruits == ProcessInputFruits::All) {
          if(someCondtion) outputFruits = ProcessedOutFruit::Grapes;
          if(anotherCondition) outputFruits = ProcessedOutFruit::Mangoes;
       }
     return ALL_GOOD_HERE;
}

Question : Is there a better way of doing this ?

  1. Can we have a subset of enums so that I can represent 1st enum as superset of 2nd enum ?
  2. Can I use input argument to be updated with the result and sent back [Probably a bad design]
  3. Need an update in the function signature ? Please suggest a better one.

What I am trying to achieve :

I am maintaining 2 different enum classes containing almost similar values which I wanted to avoid. But when I think of merging these two enum classes, it takes away the readability/clarity of the function signature

Please suggest.

Thank you.


Solution

  • A way to be able to detect overlapping elements, is that you can define enums like:

    enum class Fruits {
        None = 0,
        Apple = 1 << 0,
        Grape = 1 << 1,
        Mango = 1 << 2,
        /* Others */
        // You can define their overlap but it's not needed
        All = Apple | Grape | Mango,
    };
    

    This way each bit represents whether the enum has the given fruit. You can test for the fruit by enumVar & Fruits::Mango or for multiple fruits by enumVar & (Fruits::Mango | Fruits::Apple). You can check whether it is just a single fruit as well by enumVar == Fruits::Mango.