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

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

Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

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

Вот именно.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Decoder
Сообщения: 308
Зарегистрирован: 19 фев 2008, 23:11
Откуда: Moscow

Я чувствую, что проще самому написать конкретный пример, чем продолжать без конца этот разговор.
WinMain ведь дал уже подсказку как это реализовать.

Это собственно само объявление перечислителя...

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

typedef enum _ListOfDays
{
	Monday = 1,
	Tuesday = 2,
	Wednesday = 4,
	Thursday = 8,
	Friday = 16,
	Saturday = 32,
	Sunday = 64
} ListOfDays;
Теперь нужно создать массив из его элементов...

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

ListOfDays days[] = 
{
	Monday,
	Tuesday,
	Wednesday,
	Thursday,
	Friday,
	Saturday,
	Sunday
};
Теперь нужно создать класс, в котором операторы инкремента/декремента будут изменять индекс массива и возвращать соответствующие элементы...

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

class DayList
{
public:
	DayList() : m_index(0)
	{
	}
	operator ListOfDays()
	{
		// текущее значение
		return days[m_index];
	}
	ListOfDays operator++()
	{
		// TODO: проверить индекс!
		return days[++m_index];
	}
	ListOfDays operator--()
	{
		// TODO: проверить индекс!
		return days[--m_index];
	}
private:
	unsigned m_index;
};
Остаётся дописать лишь проверку корректности индекса, чтобы не выходить за границы массива.
И всё. Используй класс DayList в качестве управляемого енумератора.
Поумнеть несложно, куда труднее от дури избавиться.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

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

WinMain писал(а):и возвращать соответствующие константы перечислителя, то это вполне реализуемо.
Нет, так как ни какие "константы" какого то загадочного перечислителя не существуют.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Странный диалог. Я тебе говорю, что ты не прав. А ты мне отвечаешь "Вот именно" :)

По поводу перегрузки операторов. Вот простенький пример, в коротом реализованы префиксные операторы ++ и --. Их постфиксные аналоги, а так же любые другие операторы, которые понадобятся, оставляю в качестве "домашнего задания".

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

#include <stdio.h>

enum EDirection
{
   No = 0,
   Up = 1,
   Down = 2,
   Left = 3,
   Right = 4
};

EDirection& operator++(EDirection& dir)
{
   dir = (Right == dir) ? No : EDirection((int)dir + 1);
   return dir;
}

EDirection& operator--(EDirection& dir)
{
   dir = (No == dir) ? Right : EDirection((int)dir - 1);
   return dir;
}

int main()
{
   EDirection dir = Right;
   printf("dir = %d\n", (int)dir);
   ++dir;
   printf("++dir = %d\n", (int)dir);
   --dir;
   printf("--dir = %d\n", (int)dir);
   return 0;
}
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

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

Romeo писал(а):Их постфиксные аналоги
А они то мне нафига?
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на 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
Откуда: Крым, Севастополь
Контактная информация:

Сионист писал(а):Не я. Читать здесь до просветления.
Извини конечно, но указанный пост я читал раз десять, и никакого просветвления не наступило. Ты объясняешься крайне сумбурно и несвязно.
Сионист писал(а):А они то мне нафига?
Не нужны - не пиши. Моё дело предложить.
Сионист писал(а):Правильно?
Нет, не правильно. Если даже исправить все синтаксические ошибки, коих масса, то всё равно останутся логические ошибки. Например, вот это место:

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

case RightBottom: return false]
Стесняюсь спросить, а зачем так мудрить? Чем плоха вот такая имплементация?
[code=cpp]
bool operator>(TPosition left, TPosition right)
{
   return (int)left > (int)right;
}
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить