Кто его написал?Romeo писал(а):Извини конечно, но указанный пост я читал раз десять, и никакого просветвления не наступило.
Можно ли перегрузить оператор инкремента для enum?
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Тем, что как раз она то и не нужна. Наоборот, перегрузка как раз и затеяна для того, чтоб сравнивать не так.Romeo писал(а):Чем плоха вот такая имплементация?Код: Выделить всё
bool operator>(TPosition left, TPosition right) { return (int)left > (int)right; }
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Отдебаженная версия. Вот это ведёт себя, согласно замыслу. А дефолтное сравнение мне не надо.
Код: Выделить всё
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" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Проблема в том, что часть значений должна быть исключена из порядка. В данном конкретном случае NoPositon не больше ни одного другого значения, но и не меньше их, но, разумеется, и не равен. Это значение вне порядка. Кроме того, я могу воткнуть дополнительные внепорядковые значения, или может потребоваться разложить диапазон на два порядка, тогда при сравнении не равных значений из одного порядка одно из них всегда больше другого, а то меньше его, а если сравниваемые значения из разных порядков, то они просто не равны, но ни одно из них не больше и не меньше другого. Или я вообще захочу закольцевать порядок (Romeo писал(а):Неужели не проще в самом enum'е разместить его элементы в правильном порядке?
), что также нельзя свалить на оператор сравнения кодов.Шестёрка - младшая карта, туз - старшая, но шетёрка бьёт туза, при этом остальные карты бьют шестёрку, а туз бьёт остальные карты.
Не уверен. Алгоритм сравнения может вылезти всё равно и может быть таким же громоздким, при этом в кодах его будет сложнее написать. В данном случае при сравнении кодов вылазит более простой алгоритм, но это не самое сложное сравнение и самого енама.Romeo писал(а):Тогда и такой сложный оператор не придётся городить, достаточно будет сделать однострочный, сравнивающий откастованные к int'у значения.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Оператор < подразумевает сравнимость любых элементов указанного типа. Невозможно исключить некоторые значения из порядка хотя бы потому, что оператор умеет возвращать либо true, либо false, а третьего варианта наподобие no_order он возвращать не умеет. Судя по имплеменатции твоего оператора, NoPosition, который ты собирался исключить, всё же упорядочен и стоит в порядке предпоследним, перед RightBottom (так как если мы сравним RightBottom и NoPosition, мы получим false, но зато любые сравнения NoPosition c другими элементами enum'а также дадут false).
И так, если оператор < уже по природе своего возвращаемого значения подразумевает обязательный порядок всех элементов, а так же на лицо его очивидная транзитивность в нашем конкретном случае (в отличие от примера с картами), мы возвращаемся к изначальному вопросу: почему не поменять порядок элементов в enum'е, существенно упростив оператор сравнения?
Не думай, что я тебя поучаю или пытаюсь доказать, что моё мнение является единственным правильным. Если честно, я уже вышел из того возраста, когда я должен что-то кому-то доказывать. Я просто сторонник простого кода, и я пока не вижу зачем нам этот код усложнять. Если тебе твой оператор нравится больше, то Бог с ним, оставляй его.
И так, если оператор < уже по природе своего возвращаемого значения подразумевает обязательный порядок всех элементов, а так же на лицо его очивидная транзитивность в нашем конкретном случае (в отличие от примера с картами), мы возвращаемся к изначальному вопросу: почему не поменять порядок элементов в enum'е, существенно упростив оператор сравнения?
Не думай, что я тебя поучаю или пытаюсь доказать, что моё мнение является единственным правильным. Если честно, я уже вышел из того возраста, когда я должен что-то кому-то доказывать. Я просто сторонник простого кода, и я пока не вижу зачем нам этот код усложнять. Если тебе твой оператор нравится больше, то Бог с ним, оставляй его.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Это кто сказал?Romeo писал(а):Оператор < подразумевает сравнимость любых элементов указанного типа. Невозможно исключить некоторые значения из порядка
А зачем там что то третье? Вот смотри: есть некие объекты, некоторые из них распределены слева на право, а один над ними и растянут на всю ось. Сравниваем любой из объектов с верхним. И что получаем? Он левее? Нет. Значит false, уже достаточно. Но он и не правее, значит и противоположный оператор > вернёт false. И не в той же позиции, поэтому == тоже вернёт false. Что не так? Троичную логику можно сделать, хоть и не в рамках существующих языков, но троичный < не нужен в принципе, просто потому, что он отвечает на простой вопрос: меньше ли левый операнд, чем правый. Если не меньше, то false, всё.Romeo писал(а):хотя бы потому, что оператор умеет возвращать либо true, либо false, а третьего варианта наподобие
И RightBottom<NoPosition даёт false, и NoPosition<RightBottom тоже даёт false, любой алгоритм сортировки массива, часть элементов которого равны NoPosition выставит их в слабопредсказуемые места в пределах результирующего массива, зависящие и от конкретного оператора сравнения (<, <=, >=, или >) от того, как именно значения исходно распределены по индексам и от самого алгоритма, а не только от гистограммы значений.Romeo писал(а):Судя по имплеменатции твоего оператора, NoPosition, который ты собирался исключить, всё же упорядочен и стоит в порядке предпоследним, перед RightBottom (так как если мы сравним RightBottom и NoPosition, мы получим false, но зато любые сравнения NoPosition c другими элементами enum'а также дадут false).
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Код: Выделить всё
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.
Код: Выделить всё
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.
Код: Выделить всё
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.