Можно ли перегрузить оператор инкремента для enum?

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Romeo писал(а):Извини конечно, но указанный пост я читал раз десять, и никакого просветвления не наступило.
Кто его написал?
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Romeo писал(а):Чем плоха вот такая имплементация?

Код: Выделить всё

bool operator>(TPosition left, TPosition right)
{
   return (int)left > (int)right;
}
Тем, что как раз она то и не нужна. Наоборот, перегрузка как раз и затеяна для того, чтоб сравнивать не так.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Отдебаженная версия

Код: Выделить всё

bool                                        operator <                                (TPosition                         LeftOperand       ,
                                                                                       TPosition                         RightOperand      )
{
 switch (LeftOperand)
 {
  case Left       : return (RightOperand==FirstRight )||
                           (RightOperand==SecondRight)||
                           (RightOperand==Top        )||
                           (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
  case Top        : return (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
  case FirstRight : return (RightOperand==SecondRight)||
                           (RightOperand==Top        )||
                           (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
  case SecondRight: return (RightOperand==Top        )||
                           (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
  case LeftBottom : return (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
  case Bottom     : return (RightOperand==RightBottom);
  case RightBottom: return false;
 }
 return false;
}
. Вот это ведёт себя, согласно замыслу. А дефолтное сравнение мне не надо.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Всё равно ты всё усложняешь. Неужели не проще в самом enum'е разместить его элементы в правильном порядке? Тогда и такой сложный оператор не придётся городить, достаточно будет сделать однострочный, сравнивающий откастованные к int'у значения . Судя по коду твоего оператора, первым в enum'е должен стоять Left, а последним RightBottom.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Romeo писал(а):Неужели не проще в самом enum'е разместить его элементы в правильном порядке?
Проблема в том, что часть значений должна быть исключена из порядка. В данном конкретном случае NoPositon не больше ни одного другого значения, но и не меньше их, но, разумеется, и не равен. Это значение вне порядка. Кроме того, я могу воткнуть дополнительные внепорядковые значения, или может потребоваться разложить диапазон на два порядка, тогда при сравнении не равных значений из одного порядка одно из них всегда больше другого, а то меньше его, а если сравниваемые значения из разных порядков, то они просто не равны, но ни одно из них не больше и не меньше другого. Или я вообще захочу закольцевать порядок (
Шестёрка - младшая карта, туз - старшая, но шетёрка бьёт туза, при этом остальные карты бьют шестёрку, а туз бьёт остальные карты.
), что также нельзя свалить на оператор сравнения кодов.
Romeo писал(а):Тогда и такой сложный оператор не придётся городить, достаточно будет сделать однострочный, сравнивающий откастованные к int'у значения.
Не уверен. Алгоритм сравнения может вылезти всё равно и может быть таким же громоздким, при этом в кодах его будет сложнее написать. В данном случае при сравнении кодов вылазит более простой алгоритм, но это не самое сложное сравнение и самого енама.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Оператор < подразумевает сравнимость любых элементов указанного типа. Невозможно исключить некоторые значения из порядка хотя бы потому, что оператор умеет возвращать либо true, либо false, а третьего варианта наподобие no_order он возвращать не умеет. Судя по имплеменатции твоего оператора, NoPosition, который ты собирался исключить, всё же упорядочен и стоит в порядке предпоследним, перед RightBottom (так как если мы сравним RightBottom и NoPosition, мы получим false, но зато любые сравнения NoPosition c другими элементами enum'а также дадут false).

И так, если оператор < уже по природе своего возвращаемого значения подразумевает обязательный порядок всех элементов, а так же на лицо его очивидная транзитивность в нашем конкретном случае (в отличие от примера с картами), мы возвращаемся к изначальному вопросу: почему не поменять порядок элементов в enum'е, существенно упростив оператор сравнения?

Не думай, что я тебя поучаю или пытаюсь доказать, что моё мнение является единственным правильным. Если честно, я уже вышел из того возраста, когда я должен что-то кому-то доказывать. Я просто сторонник простого кода, и я пока не вижу зачем нам этот код усложнять. Если тебе твой оператор нравится больше, то Бог с ним, оставляй его.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Romeo писал(а):Оператор < подразумевает сравнимость любых элементов указанного типа. Невозможно исключить некоторые значения из порядка
Это кто сказал?
Romeo писал(а):хотя бы потому, что оператор умеет возвращать либо true, либо false, а третьего варианта наподобие
А зачем там что то третье? Вот смотри: есть некие объекты, некоторые из них распределены слева на право, а один над ними и растянут на всю ось. Сравниваем любой из объектов с верхним. И что получаем? Он левее? Нет. Значит false, уже достаточно. Но он и не правее, значит и противоположный оператор > вернёт false. И не в той же позиции, поэтому == тоже вернёт false. Что не так? Троичную логику можно сделать, хоть и не в рамках существующих языков, но троичный < не нужен в принципе, просто потому, что он отвечает на простой вопрос: меньше ли левый операнд, чем правый. Если не меньше, то false, всё.
Romeo писал(а):Судя по имплеменатции твоего оператора, NoPosition, который ты собирался исключить, всё же упорядочен и стоит в порядке предпоследним, перед RightBottom (так как если мы сравним RightBottom и NoPosition, мы получим false, но зато любые сравнения NoPosition c другими элементами enum'а также дадут false).
И RightBottom<NoPosition даёт false, и NoPosition<RightBottom тоже даёт false, любой алгоритм сортировки массива, часть элементов которого равны NoPosition выставит их в слабопредсказуемые места в пределах результирующего массива, зависящие и от конкретного оператора сравнения (<, <=, >=, или >) от того, как именно значения исходно распределены по индексам и от самого алгоритма, а не только от гистограммы значений.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Код: Выделить всё

bool                                        operator <=                               (TPosition                         LeftOperand       ,
                                                                                       TPosition                         RightOperand      )
{
 switch (LeftOperand)
 {
  case Left       : return (RightOperand==Left       )||
                           (RightOperand==FirstRight )||
                           (RightOperand==SecondRight)||
                           (RightOperand==Top        )||
                           (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
  case Top        : return (RightOperand==Top        )||
                           (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
  case FirstRight : return (RightOperand==FirstRight )||
                           (RightOperand==SecondRight)||
                           (RightOperand==Top        )||
                           (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
  case SecondRight: return (RightOperand==SecondRight)||
                           (RightOperand==Top        )||
                           (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
  case LeftBottom : return (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
  case Bottom     : return (RightOperand==RightBottom)||
                           (RightOperand==Bottom     ) ;
  case RightBottom: return (RightOperand==RightBottom);
 }
 return LeftOperand==RightOperand;
}
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Код: Выделить всё

bool                                        operator >                                (TPosition                         LeftOperand       ,
                                                                                       TPosition                         RightOperand      )
{
 switch (LeftOperand)
 {
  case Left       : return false;
  case Top        : return (RightOperand==Left       )||
                           (RightOperand==FirstRight )||
                           (RightOperand==SecondRight);
  case FirstRight : return (RightOperand==Left       );
  case SecondRight: return (RightOperand==Left       )||
                           (RightOperand==FirstRight );
  case LeftBottom : return (RightOperand==Top        )||
                           (RightOperand==Left       )||
                           (RightOperand==FirstRight )||
                           (RightOperand==SecondRight);
  case Bottom     : return (RightOperand==Top        )||
                           (RightOperand==Left       )||
                           (RightOperand==FirstRight )||
                           (RightOperand==SecondRight)||
                           (RightOperand==LeftBottom);
  case RightBottom: return (RightOperand==Top        )||
                           (RightOperand==Left       )||
                           (RightOperand==FirstRight )||
                           (RightOperand==SecondRight)||
                           (RightOperand==LeftBottom)||
                           (RightOperand==Bottom    );
 }
 return false;
}
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Код: Выделить всё

bool                                        operator >=                               (TPosition                         LeftOperand       ,
                                                                                       TPosition                         RightOperand      )
{
 switch (LeftOperand)
 {
  case Left       : return (RightOperand==Left       );
  case Top        : return (RightOperand==Left       )||
                           (RightOperand==FirstRight )||
                           (RightOperand==SecondRight)||
                           (RightOperand==Top        );
  case FirstRight : return (RightOperand==Left       )||
                           (RightOperand==FirstRight );
  case SecondRight: return (RightOperand==Left       )||
                           (RightOperand==FirstRight )||
                           (RightOperand==SecondRight);
  case LeftBottom : return (RightOperand==Top        )||
                           (RightOperand==Left       )||
                           (RightOperand==FirstRight )||
                           (RightOperand==SecondRight)||
                           (RightOperand==LeftBottom );
  case Bottom     : return (RightOperand==Top        )||
                           (RightOperand==Left       )||
                           (RightOperand==FirstRight )||
                           (RightOperand==SecondRight)||
                           (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     );
  case RightBottom: return (RightOperand==Top        )||
                           (RightOperand==Left       )||
                           (RightOperand==FirstRight )||
                           (RightOperand==SecondRight)||
                           (RightOperand==LeftBottom )||
                           (RightOperand==Bottom     )||
                           (RightOperand==RightBottom);
 }
 return LeftOperand==RightOperand;
}
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Ответить