Существует ли причина использовать перечисление для определения единственной константы в коде C++?

Здесь документация относительно приоритета оператора

in binds tighter than not

Настолько делающий, так будет служить цели

>>> (not True) in [False, True]
True

14
задан sharptooth 4 September 2009 в 12:49
поделиться

9 ответов

Причина в основном в краткости. Прежде всего, перечисление может быть анонимным:

 class foo {
    enum { bar = 1 };
 };

Это фактически вводит bar в качестве интегральной константы. Обратите внимание, что приведенное выше короче, чем static const int .

Кроме того, никто не может записать & bar , если это член enum . Если вы сделаете это:

 class foo {
    static const int bar = 1;
 }

, а затем клиент вашего класса сделает это:

 printf("%p", &foo::bar);

, тогда он получит ошибку компоновщика времени компиляции, что foo :: bar не определено (потому что, ну, как lvalue это не так). На практике, со стандартом в его нынешнем виде, везде используется полоса , где выражение интегральной константы не требуется (т. Е. Где это просто разрешено), требуется исключение из -класс определения foo :: bar. Места, где требуется такое выражение: enum инициализаторы, case метки, размер массива в типах (кроме new [] ) и шаблон аргументы целочисленных типов. Таким образом, использование бара где-либо еще технически требует определения. См. C ++ Core Language Active Issue 712 для получения дополнительной информации - на данный момент нет предлагаемых решений.

На практике большинство компиляторов в наши дни более снисходительно относятся к этому и позволят вам уйти от большинства «здравый смысл» использует переменные static const int , не требуя определения. Однако угловые случаи могут различаться, поэтому многие считают, что лучше просто использовать анонимное enum , для которого все кристально ясно и нет никакой двусмысленности.

26
ответ дан 1 December 2019 в 06:12
поделиться

Определение статических констант непосредственно в определении класса является более поздним дополнением к C ++, и многие по-прежнему придерживаются более старого обходного пути использования для этого перечисления . Возможно, до сих пор используются несколько старых компиляторов, которые не поддерживают статические константы, прямо определенные в определениях классов.

9
ответ дан 1 December 2019 в 06:12
поделиться

Единственная причина для использования "enum hack" состоит в том, что старые компиляторы не поддерживают определения констант внутри класса, как вы говорите в своем вопросе. Итак, если вы не подозреваете, что ваш код будет перенесен на старый компилятор, вам следует использовать const там, где требуется const.

5
ответ дан 1 December 2019 в 06:12
поделиться

В вашем случае я бы тоже использовал константу. Однако есть и другие случаи, когда я мог бы добавлять другие связанные константы. Примерно так:

const int TextFile = 1; // XXX Maybe add other constants for binary files etc.?

В таких случаях я сразу использую перечисление с одним значением, например:

enum FileType {
    TextFile = 1
    // XXX Maybe add other values for binary files etc.?
}

Причина в том, что компилятор может затем выдавать предупреждения, когда я использую постоянное значение в выражениях переключателя, как in:

FileType type;
// ...
switch ( type ) {
    case TextFile:
       // ...
}

В случае, если я решу добавить другое постоянное значение, которое связано с существующим значением (в данном примере это другой тип файла), практически все компиляторы выдадут предупреждение, так как новое значение не обрабатывается в переключателе оператор.

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

5
ответ дан 1 December 2019 в 06:12
поделиться

Использование перечисления имеет одно преимущество. Тип перечисления - это тип, поэтому, если вы определяете, например:

enum EnumType { EnumValue1 = 10, EnumValue2 = 20 ... };

, и у вас есть такая функция, как:

void Function1(EnumType Value)

, компилятор проверяет, что вы передаете член перечисления EnumType функции, поэтому только допустимые значения для Значение параметра будет EnumValue1 и EnumValue2. Если вы используете константы и изменяете функцию на

void Function1(int Value)

, компилятор проверяет, что вы передаете в функцию int (любой int, константу, переменную или литерал).

Перечислимые типы хороши для группировки связанных константных значений. Только для одного значения const я не вижу никаких преимуществ.

5
ответ дан 1 December 2019 в 06:12
поделиться

Я думаю, что нет причин использовать перечисление, и что на самом деле лучше использовать для этой цели static const int , поскольку перечисление имеет свой собственный тип ( даже если неявно конвертируется в целое число).

2
ответ дан 1 December 2019 в 06:12
поделиться

Между этими двумя есть разница. Насколько я знаю, у перечислений нет адреса. статические константы, хотя Поэтому, если кто-то берет адрес const static int, отбрасывает const, он может изменить значение (хотя компилятор может игнорировать изменение, потому что он думает, что это const). Это, конечно, чистое зло, и вы не должны этого делать, но компилятор не может этого предотвратить. Этого не может произойти с перечислениями.

И, конечно же - если вам (по какой-то причине) нужен адрес этой const, вам понадобится static const int.

Короче говоря, enum - это rvalue, а const static int это lvalue. См. http://www.embedded.com/story/OEG20011129S0065 для получения дополнительной информации.

2
ответ дан 1 December 2019 в 06:12
поделиться

Ну, переносимость является хорошей причиной для использования enum. Это здорово, потому что вам не нужно беспокоиться о том, поддерживает ли ваш компилятор "static const int S = 10" или нет ...

Кроме того, насколько я помню, статическая переменная должна быть где-то определена, как и объявлено, и должно быть объявлено только значение перечисления.

1
ответ дан 1 December 2019 в 06:12
поделиться

нижняя строка - используйте const.

подробнее:

Я не эксперт по C ++, но это кажется более общим вопросом дизайна.

Если это не обязательно, и вы считаете, что вероятность того, что перечисление вырастет до более чем одного значения, очень мала / отсутствует, тогда используйте обычную константу. даже если вы ошибаетесь и в какой-то момент в будущем будет больше значений, что делает enum правильным выбором - простой рефакторинг, и вы меняете const на enum.

-3
ответ дан 1 December 2019 в 06:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: