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;
--
Не можешь достичь желаемого — пожелай достигнутого.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.