А вы знали, что начиная с C++17 правила инициализации class enum были ослаблены и теперь теперь по попущению комитета объект enum'а можно инициализировать значением, которого нет в перечислении, если для enum'а указан underlying type? У меня такое впечатление, что это связано с реализацией std::byte в библиотеке. Соответственно вопрос:
Здравствуйте, B0FEE664, Вы писали:
BFE>А вы знали, что начиная с C++17 правила инициализации class enum были ослаблены и теперь теперь по попущению комитета объект enum'а можно инициализировать значением, которого нет в перечислении, если для enum'а указан underlying type? У меня такое впечатление, что это связано с реализацией std::byte в библиотеке. Соответственно вопрос: BFE>Считаете ли вы реализацию std::byte в стандарте С++ провальной?
Здравствуйте, B0FEE664, Вы писали:
BFE>А вы знали, что начиная с C++17 правила инициализации class enum были ослаблены и теперь теперь по попущению комитета объект enum'а можно инициализировать значением, которого нет в перечислении, если для enum'а указан underlying type? У меня такое впечатление, что это связано с реализацией std::byte в библиотеке.
Здравствуйте, night beast, Вы писали:
NB>можно подробнее, как это связано с std::byte?
std::byte является enum class
мдааа
сколько я не видел этих байтов, они всегда были алиасом к unsigned char
я другого варианта и не предвидел
если мне кто-то даст ссылки почитать, почему так, а не иначе задизайнили, то буду рад почитать
а пока смело в опросе ставлю провал не читал, но осуждаю
Здравствуйте, rg45, Вы писали:
R>ИМХО, это весьма полезная возможность при реализации битовых флагов и масок, которую раньше приходилось обеспечивать через хаки.
ИМХО, перечисление, флаги и маски — это три разные сущности и сделаны они должны быть с помощью трёх разных классов.
Здравствуйте, B0FEE664, Вы писали:
R>>ИМХО, это весьма полезная возможность при реализации битовых флагов и масок, которую раньше приходилось обеспечивать через хаки.
BFE>ИМХО, перечисление, флаги и маски — это три разные сущности и сделаны они должны быть с помощью трёх разных классов.
Вот прям должны? Флаги не должны задаваться перечеслениями, а битовая комбинация двух флагов должна иметь тип, отличный от типа одиночного флага?
R>Вот прям должны? Флаги не должны задаваться перечеслениями, а битовая комбинация двух флагов должна иметь тип, отличный от типа одиночного флага?
конечно не должны, но было бы неплохо если бы это было так.
Здравствуйте, Muxa, Вы писали:
R>>Вот прям должны? Флаги не должны задаваться перечеслениями, а битовая комбинация двух флагов должна иметь тип, отличный от типа одиночного флага? M>конечно не должны, но было бы неплохо если бы это было так.
Хорошо, я понял, что "не должны" здесь вносит некоторую двусмысленность, поэтому переформулирую: это плохо, когда флаги задаются перечислениями? И обязательно ли битовая комбинация флагов должна иметь тип, отличный от типа одиночного флага?
Здравствуйте, rg45, Вы писали:
R>>>ИМХО, это весьма полезная возможность при реализации битовых флагов и масок, которую раньше приходилось обеспечивать через хаки. BFE>>ИМХО, перечисление, флаги и маски — это три разные сущности и сделаны они должны быть с помощью трёх разных классов. R>Вот прям должны?
Если мы хотим иметь строго типизированный язык, то — да.
R>Флаги не должны задаваться перечеслениями, а битовая комбинация двух флагов должна иметь тип, отличный от типа одиночного флага?
Да. Я могу объяснить почему.
Разница между флагами и перечислениями:
1) у флагов и у перечислений разный набор операций. Для флагов операция | — логична, для перечисления она не имеет смысла.
2) флаги привязаны с битовому представлению, перечисления — нет.
3) этот пункт спорный, но его стоит упомянуть. Для перечисления логично иметь функции Next/Prev, а для флагов как правило они не нужны.
Разница между флагами и масками в том, что разные функции могут принимать в качестве аргументов либо маску, либо флаг, а если нет различия, то легко допустить ошибку. Например, флаг может быть конвертирован в текстовое представление, а маска, как правило — нет. Поэтому будет логично, если маску можно инициализировать флагом, а флаг маской — нет.
Есть и ещё одно различие между флагом и маской: маска может иметь значение 0, а флаг — нет.
R>Хорошо, я понял, что "не должны" здесь вносит некоторую двусмысленность, поэтому переформулирую: R>это плохо, когда флаги задаются перечислениями?
Например, при добавлении нового флага в перечисление, нужно не забыть задать ему (правильное) значение, иначе компилятор молча задаст ему неправильное как значение предыдущего+1.
При использовании, к примеру, констант забыть указать значение невозможно.
R>И обязательно ли битовая комбинация флагов должна иметь тип, отличный от типа одиночного флага?
Операции над флагами:
сравнение флагов -> bool (operator ==)
комбинация флагов -> маска (operator |)
Операции над масками:
объединить маски -> маска (operator |)
пересечь маски -> маска (operator &)
Операции над масками и флагами:
установить флаг -> маска (operator |)
сбросить флаг -> маска (operator'ы & и ~)
проверить флаг -> bool (operator &)
Невалидные операции:
флаг1 & флаг2
В скобках указано как оно обычно реализовано.
Как видишь есть пересечения, а значит неизбежны ошибки когда имели в виду одно, а написали другое, и компилятор ничего не сказал.
Здравствуйте, B0FEE664, Вы писали:
R>>Флаги не должны задаваться перечеслениями, а битовая комбинация двух флагов должна иметь тип, отличный от типа одиночного флага?
BFE>Да. Я могу объяснить почему.
BFE>Разница между флагами и перечислениями: BFE>1) у флагов и у перечислений разный набор операций. Для флагов операция | — логична, для перечисления она не имеет смысла. BFE>2) флаги привязаны с битовому представлению, перечисления — нет. BFE>3) этот пункт спорный, но его стоит упомянуть. Для перечисления логично иметь функции Next/Prev, а для флагов как правило они не нужны.
BFE>Разница между флагами и масками в том, что разные функции могут принимать в качестве аргументов либо маску, либо флаг, а если нет различия, то легко допустить ошибку. Например, флаг может быть конвертирован в текстовое представление, а маска, как правило — нет. Поэтому будет логично, если маску можно инициализировать флагом, а флаг маской — нет. BFE>Есть и ещё одно различие между флагом и маской: маска может иметь значение 0, а флаг — нет.
Это всего лишь один из подходов, со своими плюсами и минусами. В противовес можно поставить другой подход — тот, который используется в .NET и который, с некоторыми корректировками, может быть перенесен в C++ (и я это делал). В этом подходе все с точностью до наоборот. И никогда я не слышал никаких жалоб, все просто и юзабельно. И, кстати, битовые маски спокойно конвертируются не только в текстовое представление, но и обратоно:
Нет, не считаю. Моё мнение — поживем, увидим. Применили смекалочку чтобы задешево получить strong typedef
Время до C++20 еще есть, чтобы набрать практику применения, найти еще несостыковки с другими частями языка, и объявить в этом случаем нерекомендуемым к использованию, если что.
Здравствуйте, B0FEE664, Вы писали:
BFE>Если мы хотим иметь строго типизированный язык, то — да.
Всё правильно сказал, кроме того, что эта дорога приведёт нас к окамлу поверх плюсов.
Если волюнтаристски ввести, что комбинация флагов — это ад-хок маска, то легаси код сломается, а тот, который не сломается — не сломается потому, что там уже понатыкан реинтерпрет-каст.
Здравствуйте, andyp, Вы писали:
A>Здравствуйте, AleksandrN, Вы писали:
AN>>Я не понял, зачем std::byte вообще нужен и чем не устраивает uint8_t и int8_t?
A>Байт — минимально адресуемая сущность. В ней не обязательно 8 бит.
Я это знаю. Но используются ли сейчас аппаратные архитектуры, в которых байт не 8-битный? Даже если используются, не лучше ли для байта сделать целочисленный тип нужно размера, вместо enum class?
Здравствуйте, AleksandrN, Вы писали:
AN>Но используются ли сейчас аппаратные архитектуры, в которых байт не 8-битный?
Да. Архитектуру с 16ти битными байтами сам использовал.
AN>Даже если используются, не лучше ли для байта сделать целочисленный тип нужно размера, вместо enum class?
Не знаю. Может, не хотели сам язык трогать и обошлись только стандартной библиотекой. Единственное, что на ум приходит — у него выравнивание должно быть как у unsigned char. Лучше бы все таки в язык его вкрутили имхо.