Здравствуйте, boomer, Вы писали:
BFE>>enum'ы — это не графика, не время и не паралельное исполнение, так что всё отлавливается в тестах.
B>Все равно, я так и не понял, зачем enum-ы использовать не для того, для чего они предназначены. Хочется битовые флаги — что мешает использовать обычный short/int/etc.? B>Хочется типизированных флагов — написать свой класс или найти готовый библиотечный. Но нет. Надо грызть кактус и городить уродливый код, натягивая сову на глобус.
Кто-то из нас потерял нить разговора, потому что я так же против использования enum в качестве набора битовых флагов.
Здравствуйте, rg45, Вы писали:
V>>> Можешь сделать эксплисит оператор.
У>>НуЮ забыл сказать, что хочется таки чтобы выглядело также, как и с целыми флагами — без лишних приседаний
R>Увы, пока не получается
Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?
Здравствуйте, удусекшл, Вы писали:
У>>>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не? NB>>оператор в указатель на приватный мембер раньше делали... У>Хм. А в чем прикол с приватностью? Что-то не догоняю
ищи safe bool idiom
Её применение можно увидеть в исходниках std::shared_ptr
Смысл приватности в том, что с таким приватным типом почти нечего нельзя сделать.
Здравствуйте, boomer, Вы писали:
B>Опять же. Натягивание совы на глобус. Нет в перечислениях максимального и минимального. Есть просто набор значений. Вот чего не хватает — так это удобного конвертирования в строку и обратно.
Это в enum class нет максимального, а вот в просто enum — есть.
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, удусекшл, Вы писали:
BFE>>>Проблема не в том, что придётся править, а в том, что если не поправишь, то заметишь только в рантайме. У>>Или не заметишь
BFE>enum'ы — это не графика, не время и не паралельное исполнение, так что всё отлавливается в тестах.
Все равно, я так и не понял, зачем enum-ы использовать не для того, для чего они предназначены. Хочется битовые флаги — что мешает использовать обычный short/int/etc.?
Хочется типизированных флагов — написать свой класс или найти готовый библиотечный. Но нет. Надо грызть кактус и городить уродливый код, натягивая сову на глобус.
Сделал я enum class и сделал для него bitwise операторы, чтобы использовать в качестве флагов. Теперь я хочу такой флаг проверить по & и сделать то или иное, в зависимости от того, установлен этот флаг или нет. Но компилятор мне не дает — он не знает как получить из этого enum булево выражение.
В принципе, можно сделать оператор преобразования в bool, но не может ли это повлечь какие-то сайд-эффекты в виде разложенных на ровном месте граблей автоматического кастинга куда не следует?
Здравствуйте, удусекшл, Вы писали:
V>> Можешь сделать эксплисит оператор.
У>НуЮ забыл сказать, что хочется таки чтобы выглядело также, как и с целыми флагами — без лишних приседаний
Здравствуйте, удусекшл, Вы писали:
У>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?
Ну это было еще в пору C++03, когда еще не было explicit operator bool. И void* — это была самая ранняя версия, потом начали выбирать типы посложнее — разнообразные указатели на функции-члены. Но в любом случае, эти рекомендации были актуальны для классов (структур). К перечислениям эти подходы не были применимы раньше, неприменимы и сейчас.
Здравствуйте, удусекшл, Вы писали:
У>В принципе, можно сделать оператор преобразования в bool, но не может ли это повлечь какие-то сайд-эффекты в виде разложенных на ровном месте граблей автоматического кастинга куда не следует?
А как принципе, можно сделать оператор преобразования в bool для enum class? Что-то я такой возможности не помню.
У>Как бы это правильно сделать?
Правильно: сделать отдельный тип для результата operator | над элементами перечисления. Но правильно никто не делает.
Можно определить оператор ! :
enum class Mode : unsigned {
UP,
DOWN
};
bool operator! (Mode mode)
{
return Mode::UP != mode;
}
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, удусекшл, Вы писали:
У>>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?
R>Ну это было еще в пору C++03, когда еще не было explicit operator bool.
В смысле? Для операторов приведения нельзя было explicit указать?
R>И void* — это была самая ранняя версия, потом начали выбирать типы посложнее — разнообразные указатели на функции-члены.
А можно поподробнее? А то я что-то пропустил этот момент
R>Но в любом случае, эти рекомендации были актуальны для классов (структур). К перечислениям эти подходы не были применимы раньше, неприменимы и сейчас.
Здравствуйте, night beast, Вы писали:
У>>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?
NB>оператор в указатель на приватный мембер раньше делали...
Хм. А в чем прикол с приватностью? Что-то не догоняю
Здравствуйте, B0FEE664, Вы писали:
У>>В принципе, можно сделать оператор преобразования в bool, но не может ли это повлечь какие-то сайд-эффекты в виде разложенных на ровном месте граблей автоматического кастинга куда не следует?
BFE>А как принципе, можно сделать оператор преобразования в bool для enum class? Что-то я такой возможности не помню.
Здравствуйте, удусекшл, Вы писали:
У>>>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?
NB>>оператор в указатель на приватный мембер раньше делали...
У>Хм. А в чем прикол с приватностью? Что-то не догоняю
чтобы даже случайно каст не прошел, т.к. снаружи этот тип не виден.
R>>Ну это было еще в пору C++03, когда еще не было explicit operator bool. У>В смысле? Для операторов приведения нельзя было explicit указать?
Нет конечно Это фишка C++11.
R>>И void* — это была самая ранняя версия, потом начали выбирать типы посложнее — разнообразные указатели на функции-члены. У>А можно поподробнее? А то я что-то пропустил этот момент
А были еще такие маньяки (типа меня), которые специально для этих целей вводили фейковые функции, в списке формальных параметров которых присутствовали типы, определенные в закрытой секции класса — чтоб уж точно таким указателем невозможно было воспользоваться
В догонку
BFE>Правильно: сделать отдельный тип для результата operator | над элементами перечисления. Но правильно никто не делает.
Только не operator|, а operator&, наверное
В принципе, как вариант. Но иногда его нужно и по назначению использовать — результат использовать не как bool, а как тот же enum. Как бы это разрулить?
BFE>Можно определить оператор ! :
В принципе, это вариант
Но таки запись получается не очень:
if (!! (a & b) )
{
// ...
}
и без скобок низя — я так понимаю, что иначе сначала будет применен operator! к первому операнду — a, а затем bool результат будет пытаться использоваться в operator& и даст ошибку компиляции
NB>>>оператор в указатель на приватный мембер раньше делали...
У>>Хм. А в чем прикол с приватностью? Что-то не догоняю
NB>чтобы даже случайно каст не прошел, т.к. снаружи этот тип не виден.
Так это не мембер приватный, а тип приватный, так?
Здравствуйте, B0FEE664, Вы писали:
NB>>>оператор в указатель на приватный мембер раньше делали... У>>Хм. А в чем прикол с приватностью? Что-то не догоняю
BFE>ищи safe bool idiom BFE>Её применение можно увидеть в исходниках std::shared_ptr BFE>Смысл приватности в том, что с таким приватным типом почти нечего нельзя сделать.
Когда с типом — тогда стало понятнее, night beast не точно выразился
Здравствуйте, удусекшл, Вы писали:
У>>>Хм. А в чем прикол с приватностью? Что-то не догоняю
NB>>чтобы даже случайно каст не прошел, т.к. снаружи этот тип не виден.
У>Так это не мембер приватный, а тип приватный, так?
Здравствуйте, удусекшл, Вы писали:
У>Полистал тут интернеты, некоторые собаководы пишут, что enum class для флагов использовать плохо
Есть такое мнение. Но я бы не стал это воспринимать как истину в последней инстанции. Особенно с учетом всех требований стандарта. Многое указывает на то, что именно под такое использование подгонялись современные требования. Например, так называемые opague декларации, с внешними списками:
enum class Flags : unsigned {};
constexpr Flags one = 1;
constexpr Flags two = 2;
constexpr Flags one = 4;
R>Есть такое мнение. Но я бы не стал это воспринимать как истину в последней инстанции. Особенно с учетом всех требований стандарта. Многое указывает на то, что именно под такое использование подгонялись современные требования. Например, так называемые opague декларации, с внешними списками:
R>
R>enum class Flags : unsigned {};
R>constexpr Flags one = 1;
R>constexpr Flags two = 2;
R>constexpr Flags one = 4;
R>
Что-то не работает именно так. А как правильно, что-то не нагуглилось
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, удусекшл, Вы писали:
У>>Полистал тут интернеты, некоторые собаководы пишут, что enum class для флагов использовать плохо
R>Есть такое мнение. Но я бы не стал это воспринимать как истину в последней инстанции. Особенно с учетом всех требований стандарта. Многое указывает на то, что именно под такое использование подгонялись современные требования.
Хм, возможно. Но тогда почему не предоставлен механизм для использования в условных конструкциях?
Здравствуйте, удусекшл, Вы писали:
У>В догонку BFE>>Правильно: сделать отдельный тип для результата operator | над элементами перечисления. Но правильно никто не делает.
У>Только не operator|, а operator&, наверное
Это зависит от того, что вы делаете.
У>В принципе, как вариант. Но иногда его нужно и по назначению использовать — результат использовать не как bool, а как тот же enum. Как бы это разрулить?
Я говорю немного о другом. Есть перечисление влагов — это enum, а вот набор из нескольких флагов — это уже нечто большее, чем перечисление, это набор.
Если бы у меня было время и мне было не лень, то работу с флагами я бы описал как-то так:
enum class Flag : unsigned
{
Up = 1, Down=2, Left=4, Right=8
};
struct FlagSet
{
unsigned m_set;
explicit FlagSet(Flag flag) { m_set = flag;} // иногда набор состоит из одного флагаexplicit FlagSet(unsigned set) : m_set(set){} // возможно этот конструктор нужно сделать приватным, а некоторые операторы сделать друзьями
// добавить конструкторов при необходимостиoperator bool() // todo: bool safe idiome
{
return 0 == set; // return true
}
};
// объединение флагов дают набор
FlagSet operator | (Flag flag1, Flag flag2)
{
return (unsigned)flag1 | (unsigned)flag2;
}
// объединение наборов дают набор
FlagSet operator | (FlagSet mod1, FlagSet mod2)
{
return mod1.m_set | mod2.m_set;
}
// пересечение наборов дают набор
FlagSet operator & (FlagSet mod1, FlagSet mod2)
{
return mod1.m_set & mod2.m_set;
}
// пересечение набора и флага дают true если флаг присутствует в набореbool operator & (FlagSet mod, Flag flag)
{
return mod.m_set & (unsigned) flag;
}
// пересечение набора и флага дают true если флаг присутствует в набореbool operator & (Flag flag, FlagSet mod)
{
return mod & flag;
}
....
Здравствуйте, B0FEE664, Вы писали:
У>>В принципе, как вариант. Но иногда его нужно и по назначению использовать — результат использовать не как bool, а как тот же enum. Как бы это разрулить? BFE>Я говорю немного о другом. Есть перечисление влагов — это enum, а вот набор из нескольких флагов — это уже нечто большее, чем перечисление, это набор.
BFE>Если бы у меня было время и мне было не лень, то работу с флагами я бы описал как-то так:
Ок, в целом понятно. Только не понятно, зачем вводить новую сущность? Ну, может оно так и правильно, но как-то после целочисленных флагов несколько непривычно. И можно же обойтись просто структурой, в которой завернут анонимный старый добрый бесклассовый enum
Здравствуйте, удусекшл, Вы писали:
У>Ок, в целом понятно. Только не понятно, зачем вводить новую сущность?
Набор флагов — это реально новая сущьность и для отображения этого факта я ввожу новый тип FlagSet. FlagSet, кстати, следует сделать шаблонным, так как он не зависит от конкретного набора флагов.
У>Ну, может оно так и правильно, но как-то после целочисленных флагов несколько непривычно. И можно же обойтись просто структурой, в которой завернут анонимный старый добрый бесклассовый enum
Есть те, кто для расстояния, времени и скорости вводят отдельные типы, а есть те, кто записывает значения в переменные одного типа float. И те и другие могут писать качественные продукты. Тут вопрос в том, на что разработчикам нравится тратить время: на медленное построение строгой системы типов и быструю отладку или на быстрое написание кода и медленную отладку.
Здравствуйте, удусекшл, Вы писали:
У>Здравствуйте, удусекшл, Вы писали:
У>Полистал тут интернеты, некоторые собаководы пишут, что enum class для флагов использовать плохо
Собаководы абсолютно правы. Набор флагов — это совсем не перечисление. И запихивать невпихуемое — не самая лучшая идея.
Здравствуйте, удусекшл, Вы писали:
У>Здравствуйте
У>Сделал я enum class и сделал для него bitwise операторы, чтобы использовать в качестве флагов. Теперь я хочу такой флаг проверить по & и сделать то или иное, в зависимости от того, установлен этот флаг или нет. Но компилятор мне не дает — он не знает как получить из этого enum булево выражение.
А что мешает сделать функцию для проверки установлен флаг или нет?
вместо
if (a & b) ...
писать
if (a.has(b)) ...
ps: А bitwise операторах реализовал битовые сдвиги влево и вправо
Здравствуйте, kov_serg, Вы писали:
_>А что мешает сделать функцию для проверки установлен флаг или нет? _>вместо _>if (a & b) ... _>писать _>if (a.has(b)) ...
У enum'а?
_>ps: А bitwise операторах реализовал битовые сдвиги влево и вправо
Здравствуйте, удусекшл, Вы писали:
R>>Есть такое мнение. Но я бы не стал это воспринимать как истину в последней инстанции. Особенно с учетом всех требований стандарта. Многое указывает на то, что именно под такое использование подгонялись современные требования.
У>Хм, возможно. Но тогда почему не предоставлен механизм для использования в условных конструкциях?
Ну, не то чтобы совсем не предоставлен: перечисления можно использовать в switch, их можно сравнивать друг с другом. Для перечислений по-прежнему доступна zero-initialization: выражения Flags{} и Flags() конструируют "нулевой" объект перечисления, независимо от того, присутствует ли ноль в списке элементов. А значит, всегда есть возможность написать проверку: if (flags != Flags{}). Я думаю, explicit конверсию в bool просто прошляпили. И, рано или поздно, разберутся как следует и накажут кого попало, как говорится.
Здравствуйте, удусекшл, Вы писали:
У>Хм, возможно. Но тогда почему не предоставлен механизм для использования в условных конструкциях?
А пока что, я думаю, не будет большим грехом заюзать для преобразования в udnerlying type какой-нибудь унарный оператор: унарный плюс, разыменование...
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, удусекшл, Вы писали:
R>>>Есть такое мнение. Но я бы не стал это воспринимать как истину в последней инстанции. Особенно с учетом всех требований стандарта. Многое указывает на то, что именно под такое использование подгонялись современные требования.
У>>Хм, возможно. Но тогда почему не предоставлен механизм для использования в условных конструкциях?
R>Ну, не то чтобы совсем не предоставлен: перечисления можно использовать в switch, их можно сравнивать друг с другом. Для перечислений по-прежнему доступна zero-initialization: выражения Flags{} и Flags() конструируют "нулевой" объект перечисления, независимо от того, присутствует ли ноль в списке элементов. А значит, всегда есть возможность написать проверку: if (flags != Flags{}). Я думаю, explicit конверсию в bool просто прошляпили. И, рано или поздно, разберутся как следует и накажут кого попало, как говорится.
Преобразование в bool для перечисления не имеет смысл. Если, конечно, не использовать его как набор флагов. Но это само по себе, как забивание гвоздей микроскопом.
Я вообще заметил, что плюсовики любят использовать инструменты языка совсем не так, как они задумывались. Согласен, правда, что в некоторых случаях такое использование достаточно удобно.
B>Я вообще заметил, что плюсовики любят использовать инструменты языка совсем не так, как они задумывались. Согласен, правда, что в некоторых случаях такое использование достаточно удобно.
Ну, а как быть, если в языке ничего нет для типизированных флагов?
Кстати, насколько помню, такого вроде нигде нет.
Разве только в шарпе. Но и там — это enum, который ты атрибутами помечаешь, как флаги. Особо ничем не отличается от обычного enum, впрочем, только значение в строковое представление начинает форматировать по-другому.
Здравствуйте, удусекшл, Вы писали:
У>Здравствуйте, boomer, Вы писали:
B>>Я вообще заметил, что плюсовики любят использовать инструменты языка совсем не так, как они задумывались. Согласен, правда, что в некоторых случаях такое использование достаточно удобно.
У>Ну, а как быть, если в языке ничего нет для типизированных флагов?
Запилить свой тип?
У>Кстати, насколько помню, такого вроде нигде нет. У>Разве только в шарпе. Но и там — это enum, который ты атрибутами помечаешь, как флаги. Особо ничем не отличается от обычного enum, впрочем, только значение в строковое представление начинает форматировать по-другому.
Здравствуйте, boomer, Вы писали:
B>Преобразование в bool для перечисления не имеет смысл. Если, конечно, не использовать его как набор флагов. Но это само по себе, как забивание гвоздей микроскопом.
А для обычных чисел — целых, с плавающей точкой — это преобразование имеет смысл?
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, boomer, Вы писали:
B>>Преобразование в bool для перечисления не имеет смысл. Если, конечно, не использовать его как набор флагов. Но это само по себе, как забивание гвоздей микроскопом.
R>А для обычных чисел — целых, с плавающей точкой — это преобразование имеет смысл?
Это еще можно натянуть. Например, как специальное значение. И даже в этом случае лучше использовать optional. Любая неявность — это потенциальное место для дефектов.
Здравствуйте, boomer, Вы писали:
B>>>Я вообще заметил, что плюсовики любят использовать инструменты языка совсем не так, как они задумывались. Согласен, правда, что в некоторых случаях такое использование достаточно удобно.
У>>Ну, а как быть, если в языке ничего нет для типизированных флагов?
B>Запилить свой тип?
Ну вот, все и пилят, кто во что горазд. Но хотелось бы иметь такое на уровне ядра языка, ну, или хотя бы, на уровне стандартной библиотеки.
Ну, во первых, это сложно назвать нормальным языком
А во вторых — это не языковое средство, а библиотечное, что, имхо, хуже.
И, кстати, когда оно там появилось?
Здравствуйте, boomer, Вы писали:
R>>А для обычных чисел — целых, с плавающей точкой — это преобразование имеет смысл?
B>Это еще можно натянуть. Например, как специальное значение. И даже в этом случае лучше использовать optional.
Так а почему ТО можно натянуть, а ЭТО нельзя?
B>Любая неявность — это потенциальное место для дефектов.
А кто, где и что говорил про неявность? Речь же шла об операторе if. А это явное преобразование.
Здравствуйте, удусекшл, Вы писали:
У>Здравствуйте, boomer, Вы писали:
B>>>>Я вообще заметил, что плюсовики любят использовать инструменты языка совсем не так, как они задумывались. Согласен, правда, что в некоторых случаях такое использование достаточно удобно.
У>>>Ну, а как быть, если в языке ничего нет для типизированных флагов?
B>>Запилить свой тип?
У>Ну вот, все и пилят, кто во что горазд. Но хотелось бы иметь такое на уровне ядра языка, ну, или хотя бы, на уровне стандартной библиотеки.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, boomer, Вы писали:
R>>>А для обычных чисел — целых, с плавающей точкой — это преобразование имеет смысл?
B>>Это еще можно натянуть. Например, как специальное значение. И даже в этом случае лучше использовать optional.
R>Так а почему ТО можно натянуть, а ЭТО нельзя?
B>>Любая неявность — это потенциальное место для дефектов.
R>А кто, где и что говорил про неявность? Речь же шла об операторе if. А это явное преобразование.
Тогда, скажи пожалуйста, что обозначает в терминах перечислений значение, для которого вообще нет перечисления? А идея создавать объект, для которого вообще нет перечисления — еще более вредная, ИМХО.
"Типизированные" перечисления (enum class : int) — это вообще какой-то нонсенс. Попытка новый механизм сделать совместимым со старым, который и хотели починить.
Здравствуйте, boomer, Вы писали:
R>>А кто, где и что говорил про неявность? Речь же шла об операторе if. А это явное преобразование.
B>Тогда, скажи пожалуйста, что обозначает в терминах перечислений значение, для которого вообще нет перечисления?
Что-то не понял перехода. Мы же это вроде обсудили уже? Что обозначет true в терминах чисел с плавающей точкой? Но там "это можно натянуть", а тут нельзя. Так это ты мне объясни, почему двойные стандарты.
B>А идея создавать объект, для которого вообще нет перечисления — еще более вредная, ИМХО.
Ну это понятно.
B>"Типизированные" перечисления (enum class : int) — это вообще какой-то нонсенс. Попытка новый механизм сделать совместимым со старым, который и хотели починить.
Ага, сначала были плохие плюсовики, теперь вот плохой C++. Так с этого нужно было начинать.
Здравствуйте, rg45, Вы писали:
R>Ага, сначала были плохие плюсовики, теперь вот плохой C++. Так с этого нужно было начинать.
Вообще-то enum в С++ всегда был и остаётся каким-то недоразумением. Сначала значения почему-то были видны наружу enum и засоряли глобальное пространство. При этом размер занимаетмой переменной почему-то зависит от значений enum'а. Потом сделали enum class, но не подумали об частой операции, когда нужно сконвертировать значение enum'а в другой тип. Вместо того, чтобы придумать удобный синтаксис разрешили инициализацию значениями не входящими в перечисление:
#include <iostream>
#include <cstdlib>
#include <utility>
enum class EE: unsigned
{
asdf = 0, gkl = 1
};
int main() {
// your code goes here
EE x{9};
return 0;
}
Причем разрешили только для {}, а для EE x(9); — нельзя, хотя по всей остальной логике должно быть ровно наоборот. И это при том, что таких простых операций, как, например, взять максимальное значение из перечисления не предусмотрено в языке.
Здравствуйте, B0FEE664, Вы писали:
BFE>И это при том, что таких простых операций, как, например, взять максимальное значение из перечисления не предусмотрено в языке.
Я даже знаю почему. Сделай максимальное, придется делать и минимальное. А вслед за ними сумму, медиану и среднеквадратичное отклонение. Это ж как в той сказке "дай только лапку положить".
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, boomer, Вы писали:
R>>>А кто, где и что говорил про неявность? Речь же шла об операторе if. А это явное преобразование.
B>>Тогда, скажи пожалуйста, что обозначает в терминах перечислений значение, для которого вообще нет перечисления?
R>Что-то не понял перехода. Мы же это вроде обсудили уже? Что обозначет true в терминах чисел с плавающей точкой? Но там "это можно натянуть", а тут нельзя. Так это ты мне объясни, почему двойные стандарты.
Не буду спорить. Тут тоже можно натянуть. Но согласись — что в обоих случаях такое использование нельзя назвать "по назначению".
B>>"Типизированные" перечисления (enum class : int) — это вообще какой-то нонсенс. Попытка новый механизм сделать совместимым со старым, который и хотели починить.
R>Ага, сначала были плохие плюсовики, теперь вот плохой C++. Так с этого нужно было начинать.
Плюсовики не плохие. Да и сам язык тоже не плох. Переусложнен без реальной необходимости просто.
Скатываюсь в оффтопик, но все же. Лучше бы вместо новых свистоперделок сделали нормальную работу с сетью в стандартной библиотеке.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, B0FEE664, Вы писали:
BFE>>И это при том, что таких простых операций, как, например, взять максимальное значение из перечисления не предусмотрено в языке.
R>Я даже знаю почему. Сделай максимальное, придется делать и минимальное. А вслед за ними сумму, медиану и среднеквадратичное отклонение. Это ж как в той сказке "дай только лапку положить".
Опять же. Натягивание совы на глобус. Нет в перечислениях максимального и минимального. Есть просто набор значений. Вот чего не хватает — так это удобного конвертирования в строку и обратно.
Здравствуйте, boomer, Вы писали:
B>Скатываюсь в оффтопик, но все же. Лучше бы вместо новых свистоперделок сделали нормальную работу с сетью в стандартной библиотеке.
Да-да точно. И 3D графику тоже. Чтоб привыводе в поток красивые трехмерные буквы отображались.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, boomer, Вы писали:
B>>Опять же. Натягивание совы на глобус. Нет в перечислениях максимального и минимального...
R>Ну ты же видишь, тут сколько людей, столько и мнений. Слон животное большое.
И это хорошо. Любую задачу можно сделать тысячей разных способов. И любой из них будет правильным.
Здравствуйте, rg45, Вы писали:
BFE>>И это при том, что таких простых операций, как, например, взять максимальное значение из перечисления не предусмотрено в языке.
R>Я даже знаю почему. Сделай максимальное, придется делать и минимальное. А вслед за ними сумму, медиану и среднеквадратичное отклонение. Это ж как в той сказке "дай только лапку положить".
rg45, ну разумеется интерфейс взятия максимального должен быть обобщённым, таким, чтобы программист сам мог выбрать максимальное, минимальное, медиану и среднеквадратичное отклонение. Всё, что для этого надо, это уметь перечислять значения перечисления в том или ином виде.
Что-нибудь в таком виде:
enum EE
{
a, b, c, d
};
constexpr EE min = *std::min_element(std::begin<EE>(), std::end<EE>());
Или так:
for(auto en : EE)
m = std::max(m, en);
Или может, просто сказать, что для всякого перечисления X, запись X... приводит к подстановке значений перечисления в порядке объявления:
EE... ==> EE::a, EE::b, EE::c, EE::d
тогда можно будет хоть с помощью Variadic templates, хоть иначе сделать почти всё, что нужно.
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, boomer, Вы писали:
B>>Опять же. Натягивание совы на глобус. Нет в перечислениях максимального и минимального. Есть просто набор значений. Вот чего не хватает — так это удобного конвертирования в строку и обратно.
BFE>Это в enum class нет максимального, а вот в просто enum — есть.
Конечно. Я это и имел ввиду, что для перечислений нет такого понятия, как максимальное и минимальное. А то, что это было в "старых" enum — это недоразумение.
Здравствуйте, B0FEE664, Вы писали:
BFE>rg45, ну разумеется интерфейс взятия максимального должен быть обобщённым, таким, чтобы программист сам мог выбрать максимальное, минимальное, медиану и среднеквадратичное отклонение. Всё, что для этого надо, это уметь перечислять значения перечисления в том или ином виде.
BFE>Что-нибудь в таком виде: BFE>
BFE>enum EE
BFE>{
BFE> a, b, c, d
BFE>};
BFE>constexpr EE min = *std::min_element(std::begin<EE>(), std::end<EE>());
BFE>
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, B0FEE664, Вы писали:
BFE>>Это в enum class нет максимального, а вот в просто enum — есть.
R>А я-то думал, ты шутишь. Почему нет-то? Вот, твой же пример, переделанный под scoped enum-ы:
R>http://coliru.stacked-crooked.com/a/38fc39024456e980
Это работает только потому, что scoped enum — по факту такой же enum, только завернутый в свой "неймспейс". Самый настоящий костыль.
Здравствуйте, boomer, Вы писали:
B>Это работает только потому, что scoped enum — по факту такой же enum, только завернутый в свой "неймспейс". Самый настоящий костыль.
Это работает потому, что таков язык C++, на сегодняшний день, нравится тебе это или нет.
R>enum class EE {
R> a, b, c, d
R>};
R>using EE_sequence = std::integer_sequence<EE, EE::a, EE::b, EE::c, EE::d>;
R>static_assert(EE::a == min_element<EE_sequence>::value);
R>
Проблема этого кода в том, что EE не зависит от EE_sequence, а потому добавление нового значения в EE приводит к необнаружимой ошибке:
enum class EE {
a, b, c, d, e = -1
};
using EE_sequence = std::integer_sequence<EE, EE::a, EE::b, EE::c, EE::d>;
static_assert(EE::a == min_element<EE_sequence>::value);
А теперь представте, что EE используется для: конвертации в индекс массива функций обработки сообщений, конвертации в строку для лога и конвертацию в int для id сообщения — все эти последовательности придётся править руками при добавлении нового значения в EE.
Здравствуйте, B0FEE664, Вы писали:
BFE>Проблема этого кода в том, что EE не зависит от EE_sequence, а потому добавление нового значения в EE приводит к необнаружимой ошибке:
Ну это понятно. Макросы не предлагать?
BFE>А теперь представте, что EE используется для: конвертации в индекс массива функций обработки сообщений, конвертации в строку для лога и конвертацию в int для id сообщения — все эти последовательности придётся править руками при добавлении нового значения в EE.
А вот тут не понял. Допустим, есть у тебя возможность перебора, о которой ты писал выше, как это поможет тебе избежать ручной правки массива функций и строк логов?
Здравствуйте, rg45, Вы писали:
BFE>>Проблема этого кода в том, что EE не зависит от EE_sequence, а потому добавление нового значения в EE приводит к необнаружимой ошибке: R>Ну это понятно. Макросы не предлагать?
А чего их предлагать? Я пользовался довольно долгое время boost enums. Они на макросах. Ну да, можно использовать, но ведь это макросы со всеми своими неудобствами. Например, однострочные комментарии при задании перечисления приводят к странным сообщениям об ошибке.
BFE>>А теперь представте, что EE используется для: конвертации в индекс массива функций обработки сообщений, конвертации в строку для лога и конвертацию в int для id сообщения — все эти последовательности придётся править руками при добавлении нового значения в EE.
R>А вот тут не понял. Допустим, есть у тебя возможность перебора, о которой ты писал выше, как это поможет тебе избежать ручной правки массива функций и строк логов?
Проблема не в том, что придётся править, а в том, что если не поправишь, то заметишь только в рантайме.
Здравствуйте, B0FEE664, Вы писали:
BFE>А чего их предлагать? Я пользовался довольно долгое время boost enums. Они на макросах. Ну да, можно использовать, но ведь это макросы со всеми своими неудобствами. Например, однострочные комментарии при задании перечисления приводят к странным сообщениям об ошибке.
BFE>Проблема не в том, что придётся править, а в том, что если не поправишь, то заметишь только в рантайме.
Не, ну я согласен, что это было бы здорово иметь возможность перебора енумов. Но в таком случае, следовало бы поставить крест на преобразовани в энумы из underlying типов и использовании енумов для задания наборов флагов. Твою точку зрения по этому вопросу я помню, можешь не повторять
P.S. И не очень понятно, как быть с default/zero initialization.
R>>А вот тут не понял. Допустим, есть у тебя возможность перебора, о которой ты писал выше, как это поможет тебе избежать ручной правки массива функций и строк логов?
BFE>Проблема не в том, что придётся править, а в том, что если не поправишь, то заметишь только в рантайме.
Здравствуйте, удусекшл, Вы писали:
BFE>>Проблема не в том, что придётся править, а в том, что если не поправишь, то заметишь только в рантайме. У>Или не заметишь
enum'ы — это не графика, не время и не паралельное исполнение, так что всё отлавливается в тестах.
Здравствуйте, удусекшл, Вы писали:
У>Сделал я enum class и сделал для него bitwise операторы, чтобы использовать в качестве флагов.
Можно просто старый enum сделать, погружённый в структуру, например...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском