#include <iostream>
struct a {
enum LOCAL_A { A1, A2 };
};
enum class b { B1, B2 };
int foo(int input) { return input; }
int main(void) {
std::cout << foo(a::A1) << std::endl;
std::cout << foo(static_cast<int>(b::B2)) << std::endl;
}
Это a::LOCAL_A
то, чего пытается достичь строго типизированное перечисление, но есть небольшая разница: обычные перечисления могут быть преобразованы в целочисленный тип, в то время как строго типизированные перечисления не могут сделать это без приведения.
Итак, есть ли способ преобразовать строго типизированное значение перечисления в целочисленный тип без приведения? Если да, то как?
источник
Как уже говорили другие, вы не можете иметь неявное преобразование, и это просто дизайн.
Если вы хотите, вы можете избежать необходимости указывать базовый тип в приведении.
источник
Версия ответа C ++ 14, представленная Р. Мартиньо Фернандесом, будет выглядеть так:
Как и в предыдущем ответе, это будет работать с любым типом перечисления и базовым типом. Я добавил
noexcept
ключевое слово, так как оно никогда не выдаст исключение.Обновление
Это также появляется в Effective Modern C ++ Скотта Мейерса . См. Пункт 10 (он подробно описан на последних страницах этого пункта в моей копии книги).
источник
источник
Нет. Естественного пути нет .
Фактически, одна из причин строгой типизации
enum class
в C ++ 11 состоит в том, чтобы предотвратить их тихое преобразование вint
.источник
Причина отсутствия неявного преобразования (по замыслу) была дана в других ответах.
Я лично использую унарный
operator+
для преобразования из перечислимых классов в их базовый тип:Что дает довольно мало «накладных расходов»:
Где я на самом деле использую макрос для создания перечислений и функций оператора в одном кадре.
источник
Надеюсь, это поможет вам или кому-то еще
источник
un.i
это «активный член», и вы можете только читать активный член объединения.static_cast
.Короткий ответ: вы не можете, как указано выше. Но для моего случая я просто не хотел загромождать пространство имен, но все еще имел неявные преобразования, поэтому я просто сделал:
Вид пространства имен добавляет слой безопасности типов, в то время как мне не нужно статически приводить какие-либо значения перечисления к базовому типу.
источник
Foo::Foo
. Члены могут быть доступны какFoo::bar
и,Foo::baz
и могут быть неявно приведены (и поэтому не так много типов безопасности). Вероятно, лучше почти всегда использовать перечисляемые классы, особенно если начинаете новый проект.Это кажется невозможным с нативным
enum class
, но, вероятно, вы можете издеватьсяenum class
сclass
:В таком случае,
будет эквивалентно:
Это в основном эквивалентно оригиналу
enum class
. Вы можете напрямую вернутьсяb::B1
в функцию с типом возвратаb
. Вы можете делатьswitch case
с этим и т. Д.И в духе этого примера вы можете использовать шаблоны (возможно, вместе с другими вещами), чтобы обобщить и смоделировать любой возможный объект, определенный
enum class
синтаксисом.источник
Как уже говорили многие, нет способа автоматически конвертировать без добавления накладных расходов и слишком большой сложности, но вы можете немного уменьшить объем печати и улучшить ее, используя лямбды, если в сценарии будет использоваться немного приведений. Это добавит немного служебных вызовов, но сделает код более читабельным по сравнению с длинными строками static_cast, как показано ниже. Это не может быть полезным для всего проекта, но только для всего класса.
источник
Комитет C ++ сделал один шаг вперед (область видимости перечислений из глобального пространства имен) и пятьдесят шагов назад (без спада типа enum до целого числа). К сожалению,
enum class
просто не может использоваться, если вам нужно значение enum любым не символическим способом.Лучшее решение - вообще не использовать его, а вместо этого самим перечислить enum, используя пространство имен или структуру. Для этого они взаимозаменяемы. Вам нужно будет ввести немного больше, когда ссылаетесь на сам тип enum, но это, вероятно, будет не часто.
источник