Максимальное и минимальное значения в перечислении C++

Есть ли способ найти максимальное и минимальное определенные значения перечисления в С++?


person Matt    schedule 01.10.2008    source источник
comment
Взгляните на библиотеку github.com/Neargye/magic_enum.   -  person dalle    schedule 10.06.2019
comment
Одна из причин, по которой я мог бы захотеть узнать максимальное значение перечисления, не добавляя его к самому перечислению, заключается в том, что мой компилятор не жалуется (C4061), когда мой оператор 'switch' явно не обрабатывает значение максимального значения.   -  person snips-n-snails    schedule 20.11.2019


Ответы (7)


Нет, невозможно найти максимальное и минимальное определенные значения любого перечисления в C++. Когда требуется информация такого рода, рекомендуется определить значения Last и First. Например,

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

Нет необходимости указывать именованные значения для каждого значения между First и Last.

person Jeff Yates    schedule 01.10.2008
comment
По-прежнему полезно для непоследовательных перечислений - если вы не ожидаете, что каждое значение будет существовать - person Adrian Cornish; 11.01.2012
comment
@ Адриан: Да, это правда. Вам не нужно, чтобы каждое значение имело определенное имя, чтобы этот метод был полезен. Я отредактирую соответственно - person Jeff Yates; 12.01.2012
comment
хорошо, но вы должны поддерживать его значение, если добавляются новые. - person hookenz; 30.05.2019

Нет, не в стандартном C++. Вы можете сделать это вручную:

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

num_values будет содержать количество значений в перечислении.

person dalle    schedule 01.10.2008
comment
num_values ​​будет содержать числа-1 значений - person 4pie0; 19.03.2014
comment
@lizusek: num_values будет содержать количество значений в перечислении, кроме самого num_values. - person dalle; 19.03.2014
comment
@dalie да, вот почему это будет: количество значений - 1. Конечно, я знаю, что вы имеете в виду значения, которые означают значения, исключая последнее, которое не является реальным значением, а вспомогательным. Однако я бы предложил сделать это более ясным. - person 4pie0; 19.03.2014
comment
@dalle Только если val0 = 0 - person user2470258; 14.09.2017
comment
@ user2470258, как определено выше, всегда равен 0. - person dalle; 14.09.2017
comment
Я предпочитаю этот подход другим, поскольку нет необходимости обновлять его значение при добавлении новых, если он последний в списке. - person hookenz; 30.05.2019
comment
Недостатком этого подхода является то, что вводится параметр enum, который никогда не следует использовать. Вы должны доверять (или проверять), что кодеры никогда не устанавливают переменную в num_values. Из-за этого я обычно предпочитаю принятый ответ. Эта опция может быть полезна, если вы хотите иметь недопустимую опцию NA для переменных. Вы можете инициализировать переменную значением num_values ​​при ее создании. Если вы столкнетесь с этим значением позже, вы будете знать, что это значение никогда не устанавливалось в значение, отличное от значения по умолчанию. - person Ellis Miller; 05.04.2021

Нет. Перечисление в C или C++ — это просто список констант. Нет вышестоящей структуры, в которой хранилась бы такая информация.

Обычно, когда мне нужна такая информация, я включаю в перечисление максимальное и минимальное значение примерно так:

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

См. на этой веб-странице несколько примеров того, как это может быть полезно: Глупые трюки с перечислением

person Justsalt    schedule 01.10.2008
comment
статья, на которую вы ссылаетесь, относится к тому времени, когда компилятор авторов не поддерживает новый официальный логический тип С++ .... Я никогда раньше не читал что-то настолько древнее: P. - person 463035818_is_not_a_number; 23.06.2020

  enum My_enum
    {
       FIRST_VALUE = 0,

       MY_VALUE1,
       MY_VALUE2,
       ...
       MY_VALUEN,

       LAST_VALUE
    };

после определения My_enum::LAST_VALUE== N+1

person Tiendil    schedule 02.10.2008

Хотя в принятом ответе правильно указано, что не существует стандартизированного способа получить значения min и max элементов enum, в более новых версиях gcc (›= 9.0) есть по крайней мере один возможный способ, который позволяет написать это:

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
}

Это работает без каких-либо пользовательских черт или подсказок.

Это очень грубое доказательство концепции, и я уверен, что его можно расширить, просто чтобы показать, что это возможно сегодня.

Этот фрагмент компилируется в C++14, и с некоторыми изменениями он определенно может работать и в C++11, но я не думаю, что это было бы возможно в версиях до C++11

ВНИМАНИЕ. Это может привести к поломке в будущих версиях компилятора.

РЕАЛЬНАЯ ДЕМО

person ProXicT    schedule 21.05.2021

Не автоматически, но вы можете добавить искусственные значения перечисления для обозначения минимальных и максимальных значений, например.

typedef enum {start_of_colors=-1, eRed, eWhite, eBlue, eGray,
end_of_colors} eListOfTags;

for (eListOfTags i = start_of_colors+1; i < end_of_colors; i++) {
.... 
}
person wannes    schedule 21.02.2019
comment
рассмотрите возможность добавления описания, чтобы помочь с ответом. - person Bibberty; 22.02.2019

они вам даже не нужны, я просто говорю, например, если у вас есть:

enum Name{val0,val1,val2};

если у вас есть оператор switch и чтобы проверить, было ли достигнуто последнее значение, выполните следующие действия:

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

   //code
}
person Wael    schedule 23.10.2010
comment
Это очень хрупкое решение. Если вы добавите новое значение перечисления, вам придется просмотреть всю базу кода, чтобы обновить такие тесты. - person Marcelo Cantos; 04.08.2013