Enum и операции с ним

Вопрос к знающим.
Если пишем:

enum ActionList : uint8_t {
  NO_ACTION,
  DO_PRINT,
  DO_READ,
  DO_WRITE
};

ActionList action = ActionList::NO_ACTION;

void setup() {
  Serial.begin(9600);
}

void loop() {
  action = ActionList::DO_PRINT;

  switch(action) {
    case DO_PRINT: 
      Serial.println("DO PRINT");
      break;
    case DO_READ: 
      Serial.println("DO READ");
      break;
    case DO_WRITE: 
      Serial.println("DO WRITE");
      break;
    case NO_ACTION: 
      break;
  }
}

То всё отлично!

Но если сделать вот так:

enum ActionList : uint8_t {
  NO_ACTION,
  DO_PRINT,
  DO_READ,
  DO_WRITE
};

ActionList action = ActionList::NO_ACTION;

void setup() {
  Serial.begin(9600);
}

void loop() {
//  action = ActionList::DO_PRINT;
  action++;

  switch(action) {
    case DO_PRINT: 
      Serial.println("DO PRINT");
      break;
    case DO_READ: 
      Serial.println("DO READ");
      break;
    case DO_WRITE: 
      Serial.println("DO WRITE");
      break;
    case NO_ACTION: 
      break;
  }
}

Получаю:

test1.ino: In function ‘void loop()’:
test1:16:9: error: no ‘operator++(int)’ declared for postfix ‘++’ [-fpermissive]
action++;

exit status 1
no 'operator++(int)' declared for postfix '++' [-fpermissive]

Хотел определить свой, но enum - это же не тип...

Так и определите, кто мешает? Если хорошо пороетесь, я тут даже выкладывал такое определение, точно помню. Не найдёте, скажите, сам поищу.

А что?

Отнюдь!

Проблема в приведенном коде именно в том, что каждый enum в С++ - это отдельный тип.
Ваш АктионЛист вовсе не типа байт, поэтому операция инкремента для него не определена.

Попробуй вот так, в лоб

action = (ActionList)((byte)action + 1);

Нашёл пример такого оператора.

3 лайка

Ошибка. Эта страница не существует или скрыта от публичного просмотра.

Да, это в Комнате отдыха, туда неопытным вход заказан ))

Эта тема только для старожилов. Сейчас перетащу пример сюда.

enum ESensorPins {
	pinOutdoorSensor = 3,
	pinKitchenSensor = 12,
	pinBathroomSensor = 4
};

static ESensorPins getNext(const ESensorPins current) {
	switch (current) {
		case pinOutdoorSensor: return pinKitchenSensor;
		case pinKitchenSensor: return pinBathroomSensor;
		default:;
	}
	return pinOutdoorSensor;
}

ESensorPins & operator++(ESensorPins & obj) {
	obj = getNext(obj);
	return obj;
}

ESensorPins operator++(ESensorPins & obj, const int) {
	const ESensorPins copy = obj;
	obj = getNext(obj);
	return copy;
}

void setup(void) {
	Serial.begin(9600);
	Serial.println("Fun begins!");
	
	ESensorPins pin = pinKitchenSensor;
	Serial.println((int)pin);
	pin++; // переход на следующий пин
	Serial.println((int)pin);
	++pin; // переход на следующий пин
	Serial.println((int)pin);
	pin++; // переход на следующий пин
	Serial.println((int)pin);
	++pin; // переход на следующий пин
	Serial.println((int)pin);
	++++pin; // пропускаем один пин и переходим на "второй от текущего"
	Serial.println((int)pin);
}
void loop(void) {}
2 лайка

А там что? Девки в неглиже?! :face_holding_back_tears:

Подрастешь - сам увидишь )))

1 лайк
constexpr uint8_t MIN_ENUM_VALUE = 0x00;
constexpr uint8_t MAX_ENUM_VALUE = 0x03;

enum class TAction : uint8_t { Zero = 0x00, One = 0x01, Two = 0x02, Three = 0x03 };

TAction& operator ++(TAction &AValue, int) {
	uint8_t tmp = static_cast<uint8_t>(AValue);
	if (++tmp > MAX_ENUM_VALUE) tmp = MIN_ENUM_VALUE;
	AValue = static_cast<TAction>(tmp);
	return AValue;
}
TAction Action = TAction::Zero;

Потом делай Action++

Если бы только! :wink:

Получается там перегруженный перегруженный оператор ? :slight_smile:

В смысле?

Хотел новичку в его теме про его mode заданный числами сделать «по красоте». Но меня торопили (нужно было по делам срочно).
Я накидал свой оператор, но либо торопился сильно и накосячил, либо «одно из двух» :joy:

Сейчас лень компьютер включать (не могу оторваться от вкусного сыра и пива :slight_smile: ). Потом попробую еще раз, потому что тот код я не сохранил.

Евгений Петрович! Как всегда на высоте!!! Спасибо.

Деда, класс не подойдёт ему (наверное), он же новичок (да и вопрос про enum именно у меня был). Хотя уровень знаний не известен мне :slight_smile: Но всё равно спасибо)

Enum отличается от enum class только тем, что в первом случае все элементы перечисления светятся во внешнем пространстве имён, а в другом они закрыты и для доступа к ним нужно писать полный квалификатор, т.е TAction::Zero. Подумой, какие плюсы и минусы у такого подхода (кроме того, что писать дольше)

1 лайк

Хм, плаваю я с указателями )))
Так правильно?

ActionList & operator++(ActionList& AL, int) {
   AL = ActionList(AL + 1);
   return AL;
}
Полный код
enum ActionList : uint8_t {
  NO_ACTION,
  DO_PRINT,
  DO_READ,
  DO_WRITE
};

ActionList action = ActionList::NO_ACTION;

void setup() {
  Serial.begin(9600);
}

void loop() {
  //  action = ActionList::DO_PRINT;
  action++;

  switch (action) {
    case DO_PRINT:
      Serial.println("DO PRINT");
      break;
    case DO_READ:
      Serial.println("DO READ");
      break;
    case DO_WRITE:
      Serial.println("DO WRITE");
      break;
    case NO_ACTION:
      break;
  }
  delay(500);
}

ActionList & operator++(ActionList& AL, int) {
   AL = ActionList(AL + 1);
   return AL;
}

Нет

О сколько нам открытий чудных… :smiley:
Спасибо за static_cast

строго говоря, так как я написал, это неправильно, я написал постфиксный оператор ++, но ведет он себя как префиксный, за что Петрович имеет полное право намакать меня в какашки. Но я так привык чота, мне Action++ писать привычнее, чем ++Action. А реализовывать два оператора для тупого перечисления мне лень :slight_smile: