Есть ли способ проверить в C ++ 11, является ли перечисление непрерывным ?
Полностью допустимо указывать значения enum, которых нет. Есть ли такая особенность, как черта типа в C ++ 14, C ++ 17 или, может быть, C ++ 20, чтобы проверить, является ли enum непрерывным? Это будет использоваться в static_assert.
Вот небольшой пример:
enum class Types_Discontinuous {
A = 10,
B = 1,
C = 100
};
enum class Types_Continuous {
A = 0,
B = 1,
C = 2
};
static_assert(SOME_TEST<Types_Discontinuous>::value, "Enum should be continuous"); // Fails
static_assert(SOME_TEST<Types_Continuous>::value, "Enum should be continuous"); // Passes
enum
. К сожалению, у меня есть дневная работа, поэтому я не могу попытаться выписать это, хотя я буду приветствовать ответ, основанный на этом подходе. Я уверен, что кто-то вроде @barry или @sehe может это сделать.static_assert
)? Даже если вы не можете принять «красивое решение», пожалуйста, напишите ответ, так как мне очень любопытно, как это можно сделать в общем виде.Ответы:
В течение нескольких
enum
секунд вы, вероятно, сможете прорваться через это, используя библиотеку Magic Enum . Например:Обратите внимание, что это действительно, как следует из названия библиотеки, «магия» - библиотека функционирует в ряде хаков, специфичных для компилятора. Как таковой, он на самом деле не соответствует вашему требованию «чистого C ++», но, вероятно, настолько хорош, насколько мы сможем получить, пока у нас не появятся средства отражения в языке.
источник
Это невозможно в чистом C ++, потому что нет способа перечислить значения перечисления или определить количество значений, а также минимальное и максимальное значения. Но вы можете попытаться использовать помощь вашего компилятора, чтобы реализовать что-то близкое к тому, что вы хотите. Например, в gcc можно применить ошибку компиляции, если
switch
инструкция не обрабатывает все значения перечисления:Очевидно, что это специализировано для данного перечисления, но определение таких функций может быть автоматизировано с помощью препроцессора.
источник
Я хотел бы увидеть ответ на этот вопрос. Мне это тоже нужно.
К сожалению, я не думаю, что это возможно с использованием существующих утилит. Если вы хотите реализовать черту типа в этом, вам нужна поддержка вашего компилятора, поэтому написание шаблона для него не представляется возможным.
Я уже расширил перечисление специальным тегом, чтобы указать, что он является смежным, и сразу же дает вам конструктор класса enum c ++, как передать конкретное значение?
Кроме того, вы можете написать свою собственную черту:
Это должно быть специализированным всякий раз, когда вы определяете непрерывное перечисление, где вы хотите использовать это. К сожалению, это требует некоторого обслуживания и внимания, если перечисление изменяется.
источник
Все перечисления непрерывны. 0 всегда разрешено; самое высокое допустимое значение - это самый высокий перечислитель, округленный до следующего
1<<N -1
(все биты один), и все значения между ними также разрешены. ([dcl.enum] 9.7.1 / 5). Если определены отрицательные перечислители, то самое низкое допустимое значение аналогично определяется округлением в меньшую сторону перечислителя.Перечисленные в
enum
выражениях перечислители являются константными выражениями со значением в диапазоне и правильным типом, но вы можете определить дополнительные константы,enum
которые имеют те же свойства:constexpr enum class Types_Discontinuous = static_cast<Types_Discontinuous>(2)
источник