C + + 枚举中的最大值和最小值

有没有一种方法可以在 c + + 中找到枚举的最大值和最小值?

60775 次浏览

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.

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.

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

  enum My_enum
{
FIRST_VALUE = 0,


MY_VALUE1,
MY_VALUE2,
...
MY_VALUEN,


LAST_VALUE
};

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

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
}

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

If it is certain that all enum values are in ascending order (or at least the last one is guaranteed to have the greatest value) then magic enum library can be used without need to add an extra element to enum definition. It is used like this:

#include <magic_enum.hpp>
...
    

const size_t maxValue = static_cast<size_t>(magic_enum::enum_value<MyEnum>(magic_enum::enum_count<MyEnum>() - 1));

Magic enum git: https://github.com/Neargye/magic_enum