Re: Можно ли перегрузить оператор инкремента для enum?
Добавлено: 04 апр 2014, 18:00
Кто его написал?Romeo писал(а):Извини конечно, но указанный пост я читал раз десять, и никакого просветвления не наступило.
форум программистов
https://www.developing.ru/
Кто его написал?Romeo писал(а):Извини конечно, но указанный пост я читал раз десять, и никакого просветвления не наступило.
Тем, что как раз она то и не нужна. Наоборот, перегрузка как раз и затеяна для того, чтоб сравнивать не так.Romeo писал(а):Чем плоха вот такая имплементация?Код: Выделить всё
bool operator>(TPosition left, TPosition right) { return (int)left > (int)right; }
Код: Выделить всё
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;
}
Проблема в том, что часть значений должна быть исключена из порядка. В данном конкретном случае NoPositon не больше ни одного другого значения, но и не меньше их, но, разумеется, и не равен. Это значение вне порядка. Кроме того, я могу воткнуть дополнительные внепорядковые значения, или может потребоваться разложить диапазон на два порядка, тогда при сравнении не равных значений из одного порядка одно из них всегда больше другого, а то меньше его, а если сравниваемые значения из разных порядков, то они просто не равны, но ни одно из них не больше и не меньше другого. Или я вообще захочу закольцевать порядок (Romeo писал(а):Неужели не проще в самом enum'е разместить его элементы в правильном порядке?
), что также нельзя свалить на оператор сравнения кодов.Шестёрка - младшая карта, туз - старшая, но шетёрка бьёт туза, при этом остальные карты бьют шестёрку, а туз бьёт остальные карты.
Не уверен. Алгоритм сравнения может вылезти всё равно и может быть таким же громоздким, при этом в кодах его будет сложнее написать. В данном случае при сравнении кодов вылазит более простой алгоритм, но это не самое сложное сравнение и самого енама.Romeo писал(а):Тогда и такой сложный оператор не придётся городить, достаточно будет сделать однострочный, сравнивающий откастованные к int'у значения.
Это кто сказал?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).
Код: Выделить всё
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;
}
Код: Выделить всё
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;
}
Код: Выделить всё
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;
}