86

Is there a way to find the maximum and minimum defined values of an enum in c++?

Matt
  • 78,399
  • 25
  • 54
  • 67
  • Take a look at the https://github.com/Neargye/magic_enum lib – dalle Jun 10 '19 at 09:05
  • 3
    One reason I might want to know the max value of an enum without adding it to the enum itself is so my compiler doesn't complain (C4061) when my 'switch' statement does not explicitly handle the "max value" value. – snips-n-snails Nov 19 '19 at 23:59

6 Answers6

101

No, there is no way to find the maximum and minimum defined values of any enum in C++. When this kind of information is needed, it is often good practice to define a Last and First value. For example,

enum MyPretendEnum
{
   Apples,
   Oranges,
   Pears,
   Bananas,
   First = Apples,
   Last = Bananas
};

There do not need to be named values for every value between First and Last.

Jeff Yates
  • 60,114
  • 20
  • 136
  • 187
32

No, not in standard C++. You could do it manually:

enum Name
{
   val0,
   val1,
   val2,
   num_values
};

num_values will contain the number of values in the enum.

dalle
  • 17,527
  • 5
  • 54
  • 78
  • num_values will contain the numbers-1 of values – 4pie0 Mar 19 '14 at 15:21
  • 13
    @lizusek: `num_values` will contain the number of values in the enum, except `num_values` itself. – dalle Mar 19 '14 at 16:43
  • 3
    @dalie yes, that is why it will be: number of values - 1. Of course I know that you mean a values that means values excluding last one which is not a real value, but a helper. However I would suggest to make it more clearer. – 4pie0 Mar 19 '14 at 16:46
  • 1
    @dalle Only if val0 = 0 – user2470258 Sep 14 '17 at 10:12
  • @user2470258 as defined above it is always 0. – dalle Sep 14 '17 at 11:17
  • 1
    I prefer this approach over others as there is no need to update it's value when new ones are added so long as it's the last one in the list – hookenz May 30 '19 at 00:32
  • The downside of this approach is that introduces an enum option that should never be used. You have to trust (or verify) that coders never set a variable to num_values. Because of this, I normally prefer the accepted answer. On way this option can be helpful is if you wish to have an invalid NA option for variables. You can initialize a variable to num_values when instantiating it. If you encounter the value later, you know the value was never set to a non-default option. – Ellis Miller Apr 05 '21 at 06:05
7

No. An enum in C or C++ is simply a list of constants. There is no higher structure that would hold such information.

Usually when I need this kind of information I include in the enum a max and min value something like this:

enum {
  eAaa = 1,
  eBbb,
  eCccc,
  eMin = eAaaa,
  eMax = eCccc
}

See this web page for some examples of how this can be useful: Stupid Enum Tricks

Justsalt
  • 1,886
  • 3
  • 19
  • 24
  • 1
    the article you link is from a time where the authors compiler "does not support the new official C++ Boolean type" .... I have never read something that ancient before :P. – 463035818_is_not_a_number Jun 23 '20 at 11:47
5
  enum My_enum
    {
       FIRST_VALUE = 0,

       MY_VALUE1,
       MY_VALUE2,
       ...
       MY_VALUEN,

       LAST_VALUE
    };

after definition, My_enum::LAST_VALUE== N+1

Tiendil
  • 531
  • 3
  • 11
1

Although the accepted answer correctly states that there is no standardized way to get the min and max values of enum elements, there is at least one possible way in newer versions of gcc (>= 9.0), which allows to write this:

enum class Fruits { Apples, Oranges, Pears, Bananas };

int main() {
    std::cout << "Min value for Fruits is " << EnumMin<Fruits>::value << std::endl; // 0
    std::cout << "Max value for Fruits is " << EnumMax<Fruits>::value << std::endl; // 3
    std::cout << "Name: " << getName<Fruits, static_cast<Fruits>(0)>().cStr() << std::endl; // Apples
    std::cout << "Name: " << getName<Fruits, static_cast<Fruits>(3)>().cStr() << std::endl; // Bananas
    std::cout << "Name: " << getName<Fruits, static_cast<Fruits>(99)>().cStr() << std::endl; // (Fruits)99
}

This works without any custom traits or hints.

It's a very rough proof of concept and I'm sure it can be extended much further, this is just to show that this is possible today.

This snippet compiles in C++14 and with a few tweaks, it can definitely run also in C++11, but I don't think this would have been possible in pre-C++11

WARNING: This might break in the future compiler releases.

LIVE DEMO

ProXicT
  • 1,813
  • 2
  • 21
  • 45
-6

you don't even need them, what I do is just I say for example if you have:

enum Name{val0,val1,val2};

if you have switch statement and to check if the last value was reached do as the following:

if(selectedOption>=val0 && selectedOption<=val2){

   //code
}
sra
  • 23,710
  • 7
  • 54
  • 88
Wael
  • 1
  • 1
  • 21
    This is a very fragile solution. If you add a new enum value, you have to survey your entire code base to update such tests. – Marcelo Cantos Aug 04 '13 at 08:46