enum class and if expression
От: удусекшл  
Дата: 18.12.19 13:05
Оценка:
Здравствуйте

Сделал я enum class и сделал для него bitwise операторы, чтобы использовать в качестве флагов. Теперь я хочу такой флаг проверить по & и сделать то или иное, в зависимости от того, установлен этот флаг или нет. Но компилятор мне не дает — он не знает как получить из этого enum булево выражение.

В принципе, можно сделать оператор преобразования в bool, но не может ли это повлечь какие-то сайд-эффекты в виде разложенных на ровном месте граблей автоматического кастинга куда не следует?

Как бы это правильно сделать?
Отредактировано 18.12.2019 13:06 удусекшл . Предыдущая версия .
Re: enum class and if expression
От: Vamp Россия  
Дата: 18.12.19 13:22
Оценка:
У>Как бы это правильно сделать?
Можешь сделать эксплисит оператор.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 13:27
Оценка:
Здравствуйте, Vamp, Вы писали:

У>>Как бы это правильно сделать?

V> Можешь сделать эксплисит оператор.

НуЮ забыл сказать, что хочется таки чтобы выглядело также, как и с целыми флагами — без лишних приседаний
Re[3]: enum class and if expression
От: rg45 СССР  
Дата: 18.12.19 13:40
Оценка:
Здравствуйте, удусекшл, Вы писали:

V>> Можешь сделать эксплисит оператор.


У>НуЮ забыл сказать, что хочется таки чтобы выглядело также, как и с целыми флагами — без лишних приседаний


Увы, пока не получается
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 14:10
Оценка: +1
Здравствуйте, rg45, Вы писали:

V>>> Можешь сделать эксплисит оператор.


У>>НуЮ забыл сказать, что хочется таки чтобы выглядело также, как и с целыми флагами — без лишних приседаний


R>Увы, пока не получается


Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?
Re[5]: enum class and if expression
От: rg45 СССР  
Дата: 18.12.19 14:15
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?


Ну это было еще в пору C++03, когда еще не было explicit operator bool. И void* — это была самая ранняя версия, потом начали выбирать типы посложнее — разнообразные указатели на функции-члены. Но в любом случае, эти рекомендации были актуальны для классов (структур). К перечислениям эти подходы не были применимы раньше, неприменимы и сейчас.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: enum class and if expression
От: night beast СССР  
Дата: 18.12.19 14:17
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?


оператор в указатель на приватный мембер раньше делали...
Re: enum class and if expression
От: B0FEE664  
Дата: 18.12.19 14:17
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>В принципе, можно сделать оператор преобразования в bool, но не может ли это повлечь какие-то сайд-эффекты в виде разложенных на ровном месте граблей автоматического кастинга куда не следует?


А как принципе, можно сделать оператор преобразования в bool для enum class? Что-то я такой возможности не помню.

У>Как бы это правильно сделать?


Правильно: сделать отдельный тип для результата operator | над элементами перечисления. Но правильно никто не делает.

Можно определить оператор ! :

enum class Mode : unsigned {
    UP,
    DOWN
};

bool operator! (Mode mode)
{
  return Mode::UP != mode;
}

и проверять
 Mode mode = ...;
 if ( !! mode )
И каждый день — без права на ошибку...
Re[6]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 14:17
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, удусекшл, Вы писали:


У>>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?


R>Ну это было еще в пору C++03, когда еще не было explicit operator bool.


В смысле? Для операторов приведения нельзя было explicit указать?


R>И void* — это была самая ранняя версия, потом начали выбирать типы посложнее — разнообразные указатели на функции-члены.


А можно поподробнее? А то я что-то пропустил этот момент


R>Но в любом случае, эти рекомендации были актуальны для классов (структур). К перечислениям эти подходы не были применимы раньше, неприменимы и сейчас.


А, точно, есть такой нюанс
Re[6]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 14:18
Оценка:
Здравствуйте, night beast, Вы писали:

У>>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?


NB>оператор в указатель на приватный мембер раньше делали...


Хм. А в чем прикол с приватностью? Что-то не догоняю
Re[2]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 14:20
Оценка:
Здравствуйте, B0FEE664, Вы писали:

У>>В принципе, можно сделать оператор преобразования в bool, но не может ли это повлечь какие-то сайд-эффекты в виде разложенных на ровном месте граблей автоматического кастинга куда не следует?


BFE>А как принципе, можно сделать оператор преобразования в bool для enum class? Что-то я такой возможности не помню.


Да, что-то я упустил этот момент
Re[7]: enum class and if expression
От: night beast СССР  
Дата: 18.12.19 14:23
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>>>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?


NB>>оператор в указатель на приватный мембер раньше делали...


У>Хм. А в чем прикол с приватностью? Что-то не догоняю


чтобы даже случайно каст не прошел, т.к. снаружи этот тип не виден.
Re[7]: enum class and if expression
От: B0FEE664  
Дата: 18.12.19 14:25
Оценка: +1
Здравствуйте, удусекшл, Вы писали:

У>>>Что-то такое припоминается, что вроде бы ведущие собаководы рекомендовали делать operator void*, не?

NB>>оператор в указатель на приватный мембер раньше делали...
У>Хм. А в чем прикол с приватностью? Что-то не догоняю

ищи safe bool idiom
Её применение можно увидеть в исходниках std::shared_ptr
Смысл приватности в том, что с таким приватным типом почти нечего нельзя сделать.
И каждый день — без права на ошибку...
Re[7]: enum class and if expression
От: rg45 СССР  
Дата: 18.12.19 14:27
Оценка:
Здравствуйте, удусекшл, Вы писали:


R>>Ну это было еще в пору C++03, когда еще не было explicit operator bool.

У>В смысле? Для операторов приведения нельзя было explicit указать?

Нет конечно Это фишка C++11.

R>>И void* — это была самая ранняя версия, потом начали выбирать типы посложнее — разнообразные указатели на функции-члены.

У>А можно поподробнее? А то я что-то пропустил этот момент

Ну эскизно так:

class Foo
{
    typedef bool (Foo::*UnspecifiedBool)() const;
public:
    bool empty() const;
    operator UnspecifiedBool() const { !empty() ? &Foo::empty : 0; }
};


А были еще такие маньяки (типа меня), которые специально для этих целей вводили фейковые функции, в списке формальных параметров которых присутствовали типы, определенные в закрытой секции класса — чтоб уж точно таким указателем невозможно было воспользоваться
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 18.12.2019 14:31 rg45 . Предыдущая версия . Еще …
Отредактировано 18.12.2019 14:30 rg45 . Предыдущая версия .
Отредактировано 18.12.2019 14:28 rg45 . Предыдущая версия .
Re[2]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 14:32
Оценка:
Здравствуйте, B0FEE664, Вы писали:

В догонку

BFE>Правильно: сделать отдельный тип для результата operator | над элементами перечисления. Но правильно никто не делает.


Только не operator|, а operator&, наверное
В принципе, как вариант. Но иногда его нужно и по назначению использовать — результат использовать не как bool, а как тот же enum. Как бы это разрулить?


BFE>Можно определить оператор ! :


В принципе, это вариант
Но таки запись получается не очень:
if (!! (a & b) )
{
    // ...
}


и без скобок низя — я так понимаю, что иначе сначала будет применен operator! к первому операнду — a, а затем bool результат будет пытаться использоваться в operator& и даст ошибку компиляции
Re[8]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 14:32
Оценка:
Здравствуйте, night beast, Вы писали:


NB>>>оператор в указатель на приватный мембер раньше делали...


У>>Хм. А в чем прикол с приватностью? Что-то не догоняю


NB>чтобы даже случайно каст не прошел, т.к. снаружи этот тип не виден.


Так это не мембер приватный, а тип приватный, так?
Re[8]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 14:33
Оценка:
Здравствуйте, B0FEE664, Вы писали:

NB>>>оператор в указатель на приватный мембер раньше делали...

У>>Хм. А в чем прикол с приватностью? Что-то не догоняю

BFE>ищи safe bool idiom

BFE>Её применение можно увидеть в исходниках std::shared_ptr
BFE>Смысл приватности в том, что с таким приватным типом почти нечего нельзя сделать.

Когда с типом — тогда стало понятнее, night beast не точно выразился
Re[9]: enum class and if expression
От: night beast СССР  
Дата: 18.12.19 14:35
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>>>Хм. А в чем прикол с приватностью? Что-то не догоняю


NB>>чтобы даже случайно каст не прошел, т.к. снаружи этот тип не виден.


У>Так это не мембер приватный, а тип приватный, так?


и тип и мембер-функция.

https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool
Re: enum class and if expression
От: удусекшл  
Дата: 18.12.19 14:41
Оценка:
Здравствуйте, удусекшл, Вы писали:

Полистал тут интернеты, некоторые собаководы пишут, что enum class для флагов использовать плохо
Re[2]: enum class and if expression
От: rg45 СССР  
Дата: 18.12.19 14:49
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Полистал тут интернеты, некоторые собаководы пишут, что enum class для флагов использовать плохо


Есть такое мнение. Но я бы не стал это воспринимать как истину в последней инстанции. Особенно с учетом всех требований стандарта. Многое указывает на то, что именно под такое использование подгонялись современные требования. Например, так называемые opague декларации, с внешними списками:

enum class Flags : unsigned {};

constexpr Flags one = 1;
constexpr Flags two = 2;
constexpr Flags one = 4;
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 15:03
Оценка:
Здравствуйте, rg45, Вы писали:


R>Есть такое мнение. Но я бы не стал это воспринимать как истину в последней инстанции. Особенно с учетом всех требований стандарта. Многое указывает на то, что именно под такое использование подгонялись современные требования. Например, так называемые opague декларации, с внешними списками:


R>
R>enum class Flags : unsigned {};

R>constexpr Flags one = 1;
R>constexpr Flags two = 2;
R>constexpr Flags one = 4;

R>


Что-то не работает именно так. А как правильно, что-то не нагуглилось
Re[3]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 15:10
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, удусекшл, Вы писали:


У>>Полистал тут интернеты, некоторые собаководы пишут, что enum class для флагов использовать плохо


R>Есть такое мнение. Но я бы не стал это воспринимать как истину в последней инстанции. Особенно с учетом всех требований стандарта. Многое указывает на то, что именно под такое использование подгонялись современные требования.


Хм, возможно. Но тогда почему не предоставлен механизм для использования в условных конструкциях?
Re[3]: enum class and if expression
От: B0FEE664  
Дата: 18.12.19 15:28
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>В догонку

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;
}

....
И каждый день — без права на ошибку...
Re[4]: enum class and if expression
От: удусекшл  
Дата: 18.12.19 15:37
Оценка:
Здравствуйте, B0FEE664, Вы писали:

У>>В принципе, как вариант. Но иногда его нужно и по назначению использовать — результат использовать не как bool, а как тот же enum. Как бы это разрулить?

BFE>Я говорю немного о другом. Есть перечисление влагов — это enum, а вот набор из нескольких флагов — это уже нечто большее, чем перечисление, это набор.

BFE>Если бы у меня было время и мне было не лень, то работу с флагами я бы описал как-то так:


Ок, в целом понятно. Только не понятно, зачем вводить новую сущность? Ну, может оно так и правильно, но как-то после целочисленных флагов несколько непривычно. И можно же обойтись просто структурой, в которой завернут анонимный старый добрый бесклассовый enum
Re[5]: enum class and if expression
От: B0FEE664  
Дата: 18.12.19 16:19
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Ок, в целом понятно. Только не понятно, зачем вводить новую сущность?

Набор флагов — это реально новая сущьность и для отображения этого факта я ввожу новый тип FlagSet. FlagSet, кстати, следует сделать шаблонным, так как он не зависит от конкретного набора флагов.

У>Ну, может оно так и правильно, но как-то после целочисленных флагов несколько непривычно. И можно же обойтись просто структурой, в которой завернут анонимный старый добрый бесклассовый enum


Есть те, кто для расстояния, времени и скорости вводят отдельные типы, а есть те, кто записывает значения в переменные одного типа float. И те и другие могут писать качественные продукты. Тут вопрос в том, на что разработчикам нравится тратить время: на медленное построение строгой системы типов и быструю отладку или на быстрое написание кода и медленную отладку.
И каждый день — без права на ошибку...
Re[4]: enum class and if expression
От: rg45 СССР  
Дата: 18.12.19 16:32
Оценка:
Здравствуйте, удусекшл, Вы писали:

R>>
R>>enum class Flags : unsigned {};

R>>constexpr Flags one = 1;
R>>constexpr Flags two = 2;
R>>constexpr Flags one = 4;

R>>


У>Что-то не работает именно так. А как правильно, что-то не нагуглилось


Пардон, наспех писал. Вот так правильно:

enum class Flags : unsigned;

constexpr auto one = Flags(1);
constexpr auto two = Flags(2);
constexpr auto four = Flags(4);


Можно вместо auto явно писать Flags, это уже кому как нравится.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: enum class and if expression
От: boomer  
Дата: 18.12.19 17:47
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Здравствуйте, удусекшл, Вы писали:


У>Полистал тут интернеты, некоторые собаководы пишут, что enum class для флагов использовать плохо


Собаководы абсолютно правы. Набор флагов — это совсем не перечисление. И запихивать невпихуемое — не самая лучшая идея.
Re: enum class and if expression
От: kov_serg Россия  
Дата: 18.12.19 18:15
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Здравствуйте


У>Сделал я enum class и сделал для него bitwise операторы, чтобы использовать в качестве флагов. Теперь я хочу такой флаг проверить по & и сделать то или иное, в зависимости от того, установлен этот флаг или нет. Но компилятор мне не дает — он не знает как получить из этого enum булево выражение.

А что мешает сделать функцию для проверки установлен флаг или нет?
вместо
if (a & b) ...
писать
if (a.has(b)) ...

ps: А bitwise операторах реализовал битовые сдвиги влево и вправо
Re[2]: enum class and if expression
От: удусекшл  
Дата: 19.12.19 08:41
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>А что мешает сделать функцию для проверки установлен флаг или нет?

_>вместо
_>if (a & b) ...
_>писать
_>if (a.has(b)) ...

У enum'а?


_>ps: А bitwise операторах реализовал битовые сдвиги влево и вправо


Не распарсил
Re[4]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 10:17
Оценка:
Здравствуйте, удусекшл, Вы писали:

R>>Есть такое мнение. Но я бы не стал это воспринимать как истину в последней инстанции. Особенно с учетом всех требований стандарта. Многое указывает на то, что именно под такое использование подгонялись современные требования.


У>Хм, возможно. Но тогда почему не предоставлен механизм для использования в условных конструкциях?


Ну, не то чтобы совсем не предоставлен: перечисления можно использовать в switch, их можно сравнивать друг с другом. Для перечислений по-прежнему доступна zero-initialization: выражения Flags{} и Flags() конструируют "нулевой" объект перечисления, независимо от того, присутствует ли ноль в списке элементов. А значит, всегда есть возможность написать проверку: if (flags != Flags{}). Я думаю, explicit конверсию в bool просто прошляпили. И, рано или поздно, разберутся как следует и накажут кого попало, как говорится.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 19.12.2019 10:22 rg45 . Предыдущая версия . Еще …
Отредактировано 19.12.2019 10:21 rg45 . Предыдущая версия .
Re[4]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 10:51
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Хм, возможно. Но тогда почему не предоставлен механизм для использования в условных конструкциях?


А пока что, я думаю, не будет большим грехом заюзать для преобразования в udnerlying type какой-нибудь унарный оператор: унарный плюс, разыменование...

http://coliru.stacked-crooked.com/a/1eb70e86550f0a05

#include <iostream>
#include <type_traits>
#include <utility>

template <typename T>
std::enable_if_t<std::is_enum_v<T>, std::underlying_type_t<T>> operator + (T e) {
    return std::underlying_type_t<T>(e);
}

template <typename T>
std::enable_if_t<std::is_enum_v<T>, std::underlying_type_t<T>> operator * (T e) {
    return +e;
}

enum class Flags : unsigned {
    one = 1,
    two = 2,
    four = 4,
};

int main() {
    if (+Flags::one)
        std::cout << "Ok" << std::endl;

    if (*Flags::two)
        std::cout << "Ok" << std::endl;
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 19.12.2019 12:05 rg45 . Предыдущая версия . Еще …
Отредактировано 19.12.2019 10:57 rg45 . Предыдущая версия .
Отредактировано 19.12.2019 10:57 rg45 . Предыдущая версия .
Отредактировано 19.12.2019 10:56 rg45 . Предыдущая версия .
Отредактировано 19.12.2019 10:55 rg45 . Предыдущая версия .
Отредактировано 19.12.2019 10:53 rg45 . Предыдущая версия .
Re[5]: enum class and if expression
От: boomer  
Дата: 19.12.19 14:32
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, удусекшл, Вы писали:


R>>>Есть такое мнение. Но я бы не стал это воспринимать как истину в последней инстанции. Особенно с учетом всех требований стандарта. Многое указывает на то, что именно под такое использование подгонялись современные требования.


У>>Хм, возможно. Но тогда почему не предоставлен механизм для использования в условных конструкциях?


R>Ну, не то чтобы совсем не предоставлен: перечисления можно использовать в switch, их можно сравнивать друг с другом. Для перечислений по-прежнему доступна zero-initialization: выражения Flags{} и Flags() конструируют "нулевой" объект перечисления, независимо от того, присутствует ли ноль в списке элементов. А значит, всегда есть возможность написать проверку: if (flags != Flags{}). Я думаю, explicit конверсию в bool просто прошляпили. И, рано или поздно, разберутся как следует и накажут кого попало, как говорится.


Преобразование в bool для перечисления не имеет смысл. Если, конечно, не использовать его как набор флагов. Но это само по себе, как забивание гвоздей микроскопом.

Я вообще заметил, что плюсовики любят использовать инструменты языка совсем не так, как они задумывались. Согласен, правда, что в некоторых случаях такое использование достаточно удобно.
Re[6]: enum class and if expression
От: удусекшл  
Дата: 19.12.19 14:35
Оценка:
Здравствуйте, boomer, Вы писали:


B>Я вообще заметил, что плюсовики любят использовать инструменты языка совсем не так, как они задумывались. Согласен, правда, что в некоторых случаях такое использование достаточно удобно.


Ну, а как быть, если в языке ничего нет для типизированных флагов?

Кстати, насколько помню, такого вроде нигде нет.
Разве только в шарпе. Но и там — это enum, который ты атрибутами помечаешь, как флаги. Особо ничем не отличается от обычного enum, впрочем, только значение в строковое представление начинает форматировать по-другому.
Re[7]: enum class and if expression
От: boomer  
Дата: 19.12.19 14:39
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Здравствуйте, boomer, Вы писали:



B>>Я вообще заметил, что плюсовики любят использовать инструменты языка совсем не так, как они задумывались. Согласен, правда, что в некоторых случаях такое использование достаточно удобно.


У>Ну, а как быть, если в языке ничего нет для типизированных флагов?


Запилить свой тип?

У>Кстати, насколько помню, такого вроде нигде нет.

У>Разве только в шарпе. Но и там — это enum, который ты атрибутами помечаешь, как флаги. Особо ничем не отличается от обычного enum, впрочем, только значение в строковое представление начинает форматировать по-другому.

Вообще-то в нормальных языках давно есть.
https://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html
Re[6]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 14:40
Оценка:
Здравствуйте, boomer, Вы писали:

B>Преобразование в bool для перечисления не имеет смысл. Если, конечно, не использовать его как набор флагов. Но это само по себе, как забивание гвоздей микроскопом.


А для обычных чисел — целых, с плавающей точкой — это преобразование имеет смысл?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[7]: enum class and if expression
От: boomer  
Дата: 19.12.19 14:48
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, boomer, Вы писали:


B>>Преобразование в bool для перечисления не имеет смысл. Если, конечно, не использовать его как набор флагов. Но это само по себе, как забивание гвоздей микроскопом.


R>А для обычных чисел — целых, с плавающей точкой — это преобразование имеет смысл?


Это еще можно натянуть. Например, как специальное значение. И даже в этом случае лучше использовать optional. Любая неявность — это потенциальное место для дефектов.
Re[8]: enum class and if expression
От: удусекшл  
Дата: 19.12.19 14:51
Оценка:
Здравствуйте, boomer, Вы писали:

B>>>Я вообще заметил, что плюсовики любят использовать инструменты языка совсем не так, как они задумывались. Согласен, правда, что в некоторых случаях такое использование достаточно удобно.


У>>Ну, а как быть, если в языке ничего нет для типизированных флагов?


B>Запилить свой тип?


Ну вот, все и пилят, кто во что горазд. Но хотелось бы иметь такое на уровне ядра языка, ну, или хотя бы, на уровне стандартной библиотеки.


B>Вообще-то в нормальных языках давно есть.

B>https://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html

Ну, во первых, это сложно назвать нормальным языком
А во вторых — это не языковое средство, а библиотечное, что, имхо, хуже.
И, кстати, когда оно там появилось?
Re[8]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 14:53
Оценка:
Здравствуйте, boomer, Вы писали:

R>>А для обычных чисел — целых, с плавающей точкой — это преобразование имеет смысл?


B>Это еще можно натянуть. Например, как специальное значение. И даже в этом случае лучше использовать optional.


Так а почему ТО можно натянуть, а ЭТО нельзя?

B>Любая неявность — это потенциальное место для дефектов.


А кто, где и что говорил про неявность? Речь же шла об операторе if. А это явное преобразование.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 19.12.2019 15:05 rg45 . Предыдущая версия . Еще …
Отредактировано 19.12.2019 15:00 rg45 . Предыдущая версия .
Re[9]: enum class and if expression
От: boomer  
Дата: 19.12.19 15:05
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Здравствуйте, boomer, Вы писали:


B>>>>Я вообще заметил, что плюсовики любят использовать инструменты языка совсем не так, как они задумывались. Согласен, правда, что в некоторых случаях такое использование достаточно удобно.


У>>>Ну, а как быть, если в языке ничего нет для типизированных флагов?


B>>Запилить свой тип?


У>Ну вот, все и пилят, кто во что горазд. Но хотелось бы иметь такое на уровне ядра языка, ну, или хотя бы, на уровне стандартной библиотеки.



B>>Вообще-то в нормальных языках давно есть.

B>>https://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html

У>Ну, во первых, это сложно назвать нормальным языком


На вкус и цвет все фломастеры разные.

У>А во вторых — это не языковое средство, а библиотечное, что, имхо, хуже.


Если это находится в стандартной библиотеке — то никакой разницы.

У>И, кстати, когда оно там появилось?


September 2004
Re[9]: enum class and if expression
От: boomer  
Дата: 19.12.19 15:08
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, boomer, Вы писали:


R>>>А для обычных чисел — целых, с плавающей точкой — это преобразование имеет смысл?


B>>Это еще можно натянуть. Например, как специальное значение. И даже в этом случае лучше использовать optional.


R>Так а почему ТО можно натянуть, а ЭТО нельзя?


B>>Любая неявность — это потенциальное место для дефектов.


R>А кто, где и что говорил про неявность? Речь же шла об операторе if. А это явное преобразование.


Тогда, скажи пожалуйста, что обозначает в терминах перечислений значение, для которого вообще нет перечисления? А идея создавать объект, для которого вообще нет перечисления — еще более вредная, ИМХО.

"Типизированные" перечисления (enum class : int) — это вообще какой-то нонсенс. Попытка новый механизм сделать совместимым со старым, который и хотели починить.
Re[10]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 15:23
Оценка:
Здравствуйте, boomer, Вы писали:

R>>А кто, где и что говорил про неявность? Речь же шла об операторе if. А это явное преобразование.


B>Тогда, скажи пожалуйста, что обозначает в терминах перечислений значение, для которого вообще нет перечисления?


Что-то не понял перехода. Мы же это вроде обсудили уже? Что обозначет true в терминах чисел с плавающей точкой? Но там "это можно натянуть", а тут нельзя. Так это ты мне объясни, почему двойные стандарты.

B>А идея создавать объект, для которого вообще нет перечисления — еще более вредная, ИМХО.


Ну это понятно.

B>"Типизированные" перечисления (enum class : int) — это вообще какой-то нонсенс. Попытка новый механизм сделать совместимым со старым, который и хотели починить.


Ага, сначала были плохие плюсовики, теперь вот плохой C++. Так с этого нужно было начинать.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 19.12.2019 15:24 rg45 . Предыдущая версия .
Re[11]: enum class and if expression
От: B0FEE664  
Дата: 19.12.19 16:00
Оценка:
Здравствуйте, 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); — нельзя, хотя по всей остальной логике должно быть ровно наоборот. И это при том, что таких простых операций, как, например, взять максимальное значение из перечисления не предусмотрено в языке.
И каждый день — без права на ошибку...
Re[12]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 16:36
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>И это при том, что таких простых операций, как, например, взять максимальное значение из перечисления не предусмотрено в языке.


Я даже знаю почему. Сделай максимальное, придется делать и минимальное. А вслед за ними сумму, медиану и среднеквадратичное отклонение. Это ж как в той сказке "дай только лапку положить".
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 19.12.2019 16:41 rg45 . Предыдущая версия .
Re[11]: enum class and if expression
От: boomer  
Дата: 19.12.19 16:41
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, boomer, Вы писали:


R>>>А кто, где и что говорил про неявность? Речь же шла об операторе if. А это явное преобразование.


B>>Тогда, скажи пожалуйста, что обозначает в терминах перечислений значение, для которого вообще нет перечисления?


R>Что-то не понял перехода. Мы же это вроде обсудили уже? Что обозначет true в терминах чисел с плавающей точкой? Но там "это можно натянуть", а тут нельзя. Так это ты мне объясни, почему двойные стандарты.


Не буду спорить. Тут тоже можно натянуть. Но согласись — что в обоих случаях такое использование нельзя назвать "по назначению".

B>>"Типизированные" перечисления (enum class : int) — это вообще какой-то нонсенс. Попытка новый механизм сделать совместимым со старым, который и хотели починить.


R>Ага, сначала были плохие плюсовики, теперь вот плохой C++. Так с этого нужно было начинать.


Плюсовики не плохие. Да и сам язык тоже не плох. Переусложнен без реальной необходимости просто.

Скатываюсь в оффтопик, но все же. Лучше бы вместо новых свистоперделок сделали нормальную работу с сетью в стандартной библиотеке.
Re[13]: enum class and if expression
От: boomer  
Дата: 19.12.19 16:42
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, B0FEE664, Вы писали:


BFE>>И это при том, что таких простых операций, как, например, взять максимальное значение из перечисления не предусмотрено в языке.


R>Я даже знаю почему. Сделай максимальное, придется делать и минимальное. А вслед за ними сумму, медиану и среднеквадратичное отклонение. Это ж как в той сказке "дай только лапку положить".


Опять же. Натягивание совы на глобус. Нет в перечислениях максимального и минимального. Есть просто набор значений. Вот чего не хватает — так это удобного конвертирования в строку и обратно.
Re[12]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 16:44
Оценка:
Здравствуйте, boomer, Вы писали:

B>Скатываюсь в оффтопик, но все же. Лучше бы вместо новых свистоперделок сделали нормальную работу с сетью в стандартной библиотеке.


Да-да точно. И 3D графику тоже. Чтоб привыводе в поток красивые трехмерные буквы отображались.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[14]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 16:46
Оценка:
Здравствуйте, boomer, Вы писали:

B>Опять же. Натягивание совы на глобус. Нет в перечислениях максимального и минимального...


Ну ты же видишь, тут сколько людей, столько и мнений. Слон животное большое.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[15]: enum class and if expression
От: boomer  
Дата: 19.12.19 16:49
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, boomer, Вы писали:


B>>Опять же. Натягивание совы на глобус. Нет в перечислениях максимального и минимального...


R>Ну ты же видишь, тут сколько людей, столько и мнений. Слон животное большое.


И это хорошо. Любую задачу можно сделать тысячей разных способов. И любой из них будет правильным.
Re[14]: enum class and if expression
От: B0FEE664  
Дата: 19.12.19 17:19
Оценка: :)
Здравствуйте, boomer, Вы писали:

B>Опять же. Натягивание совы на глобус. Нет в перечислениях максимального и минимального. Есть просто набор значений. Вот чего не хватает — так это удобного конвертирования в строку и обратно.


Это в enum class нет максимального, а вот в просто enum — есть.
И каждый день — без права на ошибку...
Re[13]: enum class and if expression
От: B0FEE664  
Дата: 19.12.19 17:46
Оценка:
Здравствуйте, 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, хоть иначе сделать почти всё, что нужно.

for(auto en : { EE... } )
  m = std::max(m, en);
И каждый день — без права на ошибку...
Re[15]: enum class and if expression
От: boomer  
Дата: 19.12.19 17:54
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, boomer, Вы писали:


B>>Опять же. Натягивание совы на глобус. Нет в перечислениях максимального и минимального. Есть просто набор значений. Вот чего не хватает — так это удобного конвертирования в строку и обратно.


BFE>Это в enum class нет максимального, а вот в просто enum — есть.


Конечно. Я это и имел ввиду, что для перечислений нет такого понятия, как максимальное и минимальное. А то, что это было в "старых" enum — это недоразумение.
Re[14]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 18:23
Оценка:
Здравствуйте, 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>


В том или ином виде, это и так можно делать:

http://coliru.stacked-crooked.com/a/0581c82ed5e14b44

template<typename>
struct min_element;

template<typename T, T head, T...tail>
struct min_element<std::integer_sequence<T, head, tail...>> {
    static constexpr T value = std::min(head, min_element<std::integer_sequence<T, tail...>>::value);
};

template<typename T, T head>
struct min_element<std::integer_sequence<T, head>> {
    static constexpr T value = head;
};

enum EE {
    a, b, c, d
};
using EE_sequence = std::integer_sequence<EE, a, b, c, d>;

static_assert(a == min_element<EE_sequence>::value);
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[15]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 18:47
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Это в enum class нет максимального, а вот в просто enum — есть.



А я-то думал, ты шутишь. Почему нет-то? Вот, твой же пример, переделанный под scoped enum-ы:

http://coliru.stacked-crooked.com/a/38fc39024456e980

template<typename>
struct min_element;

template<typename T, T head, T...tail>
struct min_element<std::integer_sequence<T, head, tail...>> {
    static constexpr T value = std::min(head, min_element<std::integer_sequence<T, tail...>>::value);
};

template<typename T, T head>
struct min_element<std::integer_sequence<T, head>> {
    static constexpr T value = head;
};

enum class EE {
    a, b, c, d
};
using EE_sequence = std::integer_sequence<EE, EE::a, EE::b, EE::c, EE::d>;

static_assert(EE::a == min_element<EE_sequence>::value);
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[16]: enum class and if expression
От: boomer  
Дата: 19.12.19 19:32
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, B0FEE664, Вы писали:


BFE>>Это в enum class нет максимального, а вот в просто enum — есть.


R>А я-то думал, ты шутишь. Почему нет-то? Вот, твой же пример, переделанный под scoped enum-ы:


R>http://coliru.stacked-crooked.com/a/38fc39024456e980


Это работает только потому, что scoped enum — по факту такой же enum, только завернутый в свой "неймспейс". Самый настоящий костыль.
Re[17]: enum class and if expression
От: rg45 СССР  
Дата: 19.12.19 19:36
Оценка:
Здравствуйте, boomer, Вы писали:

B>Это работает только потому, что scoped enum — по факту такой же enum, только завернутый в свой "неймспейс". Самый настоящий костыль.


Это работает потому, что таков язык C++, на сегодняшний день, нравится тебе это или нет.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[16]: enum class and if expression
От: B0FEE664  
Дата: 20.12.19 10:26
Оценка:
Здравствуйте, rg45, Вы писали:

R>
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.
И каждый день — без права на ошибку...
Отредактировано 20.12.2019 10:32 B0FEE664 . Предыдущая версия .
Re[17]: enum class and if expression
От: rg45 СССР  
Дата: 20.12.19 11:05
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Проблема этого кода в том, что EE не зависит от EE_sequence, а потому добавление нового значения в EE приводит к необнаружимой ошибке:


Ну это понятно. Макросы не предлагать?

BFE>А теперь представте, что EE используется для: конвертации в индекс массива функций обработки сообщений, конвертации в строку для лога и конвертацию в int для id сообщения — все эти последовательности придётся править руками при добавлении нового значения в EE.


А вот тут не понял. Допустим, есть у тебя возможность перебора, о которой ты писал выше, как это поможет тебе избежать ручной правки массива функций и строк логов?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[18]: enum class and if expression
От: B0FEE664  
Дата: 20.12.19 11:25
Оценка:
Здравствуйте, rg45, Вы писали:

BFE>>Проблема этого кода в том, что EE не зависит от EE_sequence, а потому добавление нового значения в EE приводит к необнаружимой ошибке:

R>Ну это понятно. Макросы не предлагать?
А чего их предлагать? Я пользовался довольно долгое время boost enums. Они на макросах. Ну да, можно использовать, но ведь это макросы со всеми своими неудобствами. Например, однострочные комментарии при задании перечисления приводят к странным сообщениям об ошибке.

BFE>>А теперь представте, что EE используется для: конвертации в индекс массива функций обработки сообщений, конвертации в строку для лога и конвертацию в int для id сообщения — все эти последовательности придётся править руками при добавлении нового значения в EE.


R>А вот тут не понял. Допустим, есть у тебя возможность перебора, о которой ты писал выше, как это поможет тебе избежать ручной правки массива функций и строк логов?


Проблема не в том, что придётся править, а в том, что если не поправишь, то заметишь только в рантайме.
И каждый день — без права на ошибку...
Re[19]: enum class and if expression
От: rg45 СССР  
Дата: 20.12.19 11:37
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>А чего их предлагать? Я пользовался довольно долгое время boost enums. Они на макросах. Ну да, можно использовать, но ведь это макросы со всеми своими неудобствами. Например, однострочные комментарии при задании перечисления приводят к странным сообщениям об ошибке.


BFE>Проблема не в том, что придётся править, а в том, что если не поправишь, то заметишь только в рантайме.


Не, ну я согласен, что это было бы здорово иметь возможность перебора енумов. Но в таком случае, следовало бы поставить крест на преобразовани в энумы из underlying типов и использовании енумов для задания наборов флагов. Твою точку зрения по этому вопросу я помню, можешь не повторять

P.S. И не очень понятно, как быть с default/zero initialization.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 20.12.2019 11:49 rg45 . Предыдущая версия .
Re[19]: enum class and if expression
От: удусекшл  
Дата: 20.12.19 11:57
Оценка:
Здравствуйте, B0FEE664, Вы писали:


R>>А вот тут не понял. Допустим, есть у тебя возможность перебора, о которой ты писал выше, как это поможет тебе избежать ручной правки массива функций и строк логов?


BFE>Проблема не в том, что придётся править, а в том, что если не поправишь, то заметишь только в рантайме.



Или не заметишь
Re[20]: enum class and if expression
От: B0FEE664  
Дата: 20.12.19 12:13
Оценка:
Здравствуйте, удусекшл, Вы писали:

BFE>>Проблема не в том, что придётся править, а в том, что если не поправишь, то заметишь только в рантайме.

У>Или не заметишь

enum'ы — это не графика, не время и не паралельное исполнение, так что всё отлавливается в тестах.
И каждый день — без права на ошибку...
Re[21]: enum class and if expression
От: boomer  
Дата: 20.12.19 15:21
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, удусекшл, Вы писали:


BFE>>>Проблема не в том, что придётся править, а в том, что если не поправишь, то заметишь только в рантайме.

У>>Или не заметишь

BFE>enum'ы — это не графика, не время и не паралельное исполнение, так что всё отлавливается в тестах.


Все равно, я так и не понял, зачем enum-ы использовать не для того, для чего они предназначены. Хочется битовые флаги — что мешает использовать обычный short/int/etc.?
Хочется типизированных флагов — написать свой класс или найти готовый библиотечный. Но нет. Надо грызть кактус и городить уродливый код, натягивая сову на глобус.
Re[22]: enum class and if expression
От: B0FEE664  
Дата: 20.12.19 16:23
Оценка: +1 :)
Здравствуйте, boomer, Вы писали:

BFE>>enum'ы — это не графика, не время и не паралельное исполнение, так что всё отлавливается в тестах.


B>Все равно, я так и не понял, зачем enum-ы использовать не для того, для чего они предназначены. Хочется битовые флаги — что мешает использовать обычный short/int/etc.?

B>Хочется типизированных флагов — написать свой класс или найти готовый библиотечный. Но нет. Надо грызть кактус и городить уродливый код, натягивая сову на глобус.

Кто-то из нас потерял нить разговора, потому что я так же против использования enum в качестве набора битовых флагов.
И каждый день — без права на ошибку...
Re: enum class and if expression
От: swingus  
Дата: 04.01.20 05:19
Оценка:
Я не парюсь и делаю так:


#include <type_traits>

template <typename T>
auto has_feature(T t, T f) -> bool
{ 
   return static_cast<std::underlying_type_t<T>>(t & f) != 0;
}


или


#include <type_traits>

template <typename T>
   requires 
    std::is_enum_v<T>
     && (T t, T f){ { t & f } -> T; }
auto has_feature(T t, T f) -> bool
{ 
   return static_cast<std::underlying_type_t<T>>(t & f) != 0;
}


или даже


#include <type_traits>
#include <concepts>

template <typename T>
   requires 
    (std::is_enum_v<T> || std::integral<T>)
     && (T t, T f){ { t & f } -> T; }
auto has_feature(T t, T f) -> bool
{ 
   return t & f != static_cast<T>(0);
}


Здравствуйте, удусекшл, Вы писали:

У>Здравствуйте


У>Как бы это правильно сделать?
Re: enum class and if expression
От: Erop Россия  
Дата: 05.01.20 23:31
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Сделал я enum class и сделал для него bitwise операторы, чтобы использовать в качестве флагов.


Можно просто старый enum сделать, погружённый в структуру, например...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.