Open apolukhin opened 3 years ago
Nate Reinar Windwood, 17 апреля 2019, 19:46 Контрпродуктивно: вся суть enum class в строгой типизации. Если нужен только скоупинг — засуньте enum в неймспейс.
Удалённый пользователь, 18 апреля 2019, 15:51 Nate Reinar Windwood, enum class очень удобно в компайл тайм вычеслениях, а реальный пример где можно использовать его в рантайм есть? Я свой проекте все enum ы перевел на enum class и об этом сожелел, пришлось для каждого enum class написать операция сравнений на int . Конца, концов отказал от этий идей.
Удалённый пользователь, 18 апреля 2019, 15:57
// Вот один пример.
struct table_row
{
int id;
int color;
};
enum class color{ red, blue, white } ;
void read_from_db(table_row& row)
{
row = read_from_outside_library();
// Не комплириуется без operator != ( int , enum color ) overload.
if ( row.color != color::red && row.color != color::blue && row.color != color.white )
throw std::runtime_error("row.color invalid");
}
Удалённый пользователь, 18 апреля 2019, 16:05 Я не предлагаю, изменить каких либо свойства enum class а.
Предлагаю, implicit добавить operation == , != , < , > , <= , >= с enum class and its underlying-type.
Например, если вот эту компилятор сам генерирует, будет здорово!
template< typename Enum >
bool operator == ( Enum e, typename std::underlying_type<Enum>::type value)
{
return static_cast< typename std::underlying_type<Enum>::type > ( e ) == value ;
}
template< typename Enum >
bool operator == ( typename std::underlying_type<Enum>::type value , Enum e)
{
return static_cast< typename std::underlying_type<Enum>::type > ( e ) == value ;
}
Виктор Губин, 2 августа 2019, 12:38 Чем вас не устраивает
switch( static_cast<color>(value) )
?
Внутри enum так или иначе это unsigned integer, есть только возможность "подрезать" тип. Скажем для Windows/DOS символов консоли,
enum class color: uint8_t { red = 0x04; green = 0x02; blue = 0x01 };
естественно static_cast попросту сведет байт к двойному слову.
К сожалению привять дополнительное константное значаение другого типа прямо внути enum С++ нельзя, хотя было-бы очень полезным:
enum class error_condition {
ok("no error") = 0,
file_not_found("no such file or directory") = 1
public:
constexp const char* message() const noexcept {
return msg_;
}
private:
explicit constexpr error_condition(const char* msg) noexcept:
msg_(msg)
{}
const char* msg_;
}
Тогда вообще отпадет надобность писать switch, достаточно просто спросить у константы
ec.message()
Чем вас не устраивает
switch( static_cast<color>(value) )
?
Это UB, если value нековертируем
template< typename Enum > bool operator == ( Enum e, typename std::underlying_type<Enum>::type value) { return static_cast< typename std::underlying_type<Enum>::type > ( e ) == value ; } template< typename Enum > bool operator == ( typename std::underlying_type<Enum>::type value , Enum e) { return static_cast< typename std::underlying_type<Enum>::type > ( e ) == value ; }
А это - почти полное стирание грани между enum class и enum classic. Если добавить еще operator=
, то будет совсем полное.
Лучше бы в стандартную библиотеку добавить такое:
enum class Enum
{
X = 1,
Y = 100,
};
std::is_enumerated<Enum>(1); // true
std::is_enumerated<Enum>(101); // false
Объявить реализацию как unspecified
и жить спокойно в ожидании нормальной рефлексии (которую хрен пойми когда привезут).
Перенос предложения: голоса +3, -7 Автор идеи: ??
Пример, который не скомплируется в с++11 или слудующих версий, потому что enum color не конвертируется на "int" . Но в switch case здесь никакое присваивание enum color на каких либо int не происходят.
Предлагаю, добавить автогенерация оператор сравнение enum class с его underlying type . Чтобы легко сравнивать и использовать их в if else , switch case и других местах.
Тот пример , изменим и делаем работающий код для нынешного стандарт С++, будет UB:
Если не ошибаюсь, в с++17 конвертация целый число в enum class будет UB, если этот целый число значение имеет больше бит чем enum class элементы используется. В данном случий, enum class color -- элементам хватить 3 бит, а "value" переменный может имет любой допустимый значений.