Есть ли способ указать конструктор по умолчанию для enum class
?
Я использую enum class
, чтобы указать набор значений, допустимых для определенного типа данных в библиотеке: в данном случае это номера идентификаторов выводов GPIO Raspberry Pi. Это выглядит примерно так:
enum class PinID : int {N4 = 4, N17 = 17, /* ...etc... */ }
Смысл в том, что я делаю это вместо того, чтобы просто использовать, скажем, int
, чтобы убедиться, что код безопасен: я могу static_assert
(или иначе во время компиляции гарантировать - фактический используемый метод не важен для меня) такие вещи, как те, которые кто-то не не сделал орфографическую ошибку (пропустил 5 вместо 4 и т. д.), и я получаю автоматические сообщения об ошибках при несоответствии типов и т. д.
Тогда проблема заключается в том, что enum class
имеет конструктор по умолчанию, который - я полагаю, ради совместимости с enum
s C (поскольку у них одинаковое поведение) - инициализируется enum class
эквивалентом 0
. В этом случае значение 0
отсутствует. Это означает, что пользователь делает объявление/определение, например:
PinID pid = PinID();
получает перечислитель, который явно не определен (и даже не кажется «существующим», если взглянуть на код), и может привести к ошибкам во время выполнения. Это также означает, что такие методы, как switch
ing над значениями явно определенных перечислителей, невозможны без наличия случая ошибки/по умолчанию - чего я хочу избежать, поскольку это заставляет меня либо throw
, либо делать что-то вроде возврата boost::optional
, что менее приемлемо. к статическому анализу.
Я пытался определить конструктор по умолчанию безрезультатно. Я (отчаянно) пытался определить функцию, которая имеет то же имя, что и enum class
, но это (довольно неудивительно) привело к странным ошибкам компилятора. Я хочу сохранить возможность приведения enum class
к int
, при этом все перечислители N#
сопоставляются с их соответствующими #
, поэтому простое "определение", скажем, N4 = 0 неприемлемо; это для простоты и здравомыслия.
Я предполагаю, что мой вопрос двоякий: есть ли способ получить статическую безопасность, которую я получаю после использования enum class
? Если нет, то какие другие возможности можно было бы предпочесть? Я хочу что-то, что:
- является конструктивным по умолчанию
- можно сделать конструкцию по умолчанию произвольной допустимой величиной
- предоставляет «конечный набор указанных» значений, предоставляемых
enum class
es - по крайней мере так же безопасен, как
enum class
- (предпочтительно) не включает полиморфизм во время выполнения
Причина, по которой мне нужна конструктивность по умолчанию, заключается в том, что я планирую использовать boost::lexical_cast
для уменьшения синтаксических издержек, связанных с преобразованиями между значениями enum class
и фактическими связанными string
, которые я вывожу в операционную систему (в данном случае sysfs); boost::lexical_cast
требует конструктивности по умолчанию.
Ошибки в моих рассуждениях приветствуются — я начинаю подозревать, что в данном случае enum class
es — правильный объект для неправильной работы; разъяснение будет предложено, если спросят. Спасибо за ваше время.