Re[5]: Строгие перечисления в С++
От: MShura  
Дата: 04.08.10 22:20
Оценка:
bnk>>const char* getOptionValue(Option option)
bnk>>{
bnk>> switch (option)
bnk>> {
bnk>> case Option_One: return "Value1";
bnk>> case Option_Two: return "Value2";
bnk>> }
bnk>>}
V>Здесь можно забыть добавить case для свитча.

Компилите не только cl, но и gcc.
Он на не полный switch для enum выдает warning
Re[7]: Собираются ли последние версии QT в Visual Studio ?
От: rsdntchkru  
Дата: 04.08.10 23:00
Оценка: +2
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, rsdntchkru, Вы писали:


V>>>>>...

V>>>>>Можно ещё наворотов добавить, вроде итератора по значениям енума (через boost::mpl) и перегрузить операторы, чтобы делать операции над значениями енума.
R>>>>ужос! это пример как из простого сделать нечитабельно-неподдерживаемое сложное?
V>>>Вы вариант remark'а видели? Так ещё больший ужос, лучше вам в программирование нос не совать, там много ужософ ходят..
R>>Да уж, наверно надо было не совать. К сожалению как 17 лет назад засунул, так все там. И все еще не перстаю порой удивляться ширине пытливой мысли некоторых программистов типа как приведенной в варианте 4 этой статьи. Если из обычного enuma такую тему можно было развить, то что будет если они код для пузырьковой сортировки опишут? Роман на 500 листов
V>Не будет романов, std::sort решает в большинстве, похоже за 17 лет вы не в курсе про него
Не удивлюсь если напишут. А вы, я уверен, придумаете на это еще более изощренный вариант
Re: Строгие перечисления в С++
От: The Lex Украина  
Дата: 07.08.10 09:41
Оценка:
Здравствуйте, Вьюков Д. С., Тепляков С. В., Вы писали:

ВДС>В данной статье рассмотрены несколько решений, позволяющих ослабить или практически полностью избавиться от недостатков перечислений (enumerations) языка программирования С++. Представленные решения, отличаются сложностью реализации и функциональностью, и могут оказаться полезными в арсенале каждого современного разработчика.


Мне трепетно возражать истинным гуру, но по моему скромному мнению уже за это:

switch(c.GetValue())
{
    //Использовать выражение Color::Red().GetValue() в блоках
    //case нельзя, т.к. это выражение не является константой
    //времени компиляции.
    //Специально для этой цели внутри каждого класса
    //определяется внутреннее перечисление, которое содержит
    //все значения констант с завершающим символом "_"
    case Color::Red_:
      std::cout << "Hello, Red color!" << std::endl;
      break;
}


Весь вариант 4 можно смело отправлять в раздел специальных решений под конкретную бизнес-задачу. Причем условия этой бизнес задачи прямо указаны в статье:

Вариант 4. Строгое перечисление
Это наиболее функциональный, но и наиболее сложный в реализации вариант, который позволяет следующее:
...


Цитировать весь текст не буду, но по-моему решается как раз очень конкретная задача, к общему "типу перечислений и использованию" отношения прямо не имеющая. И это, имхо, правильно. При необходимости оперировать в пространстве задачи неким "специальным типом перечисления" его и следует создавать и оперировать им как специальным нашим бизнес-объектом с нужными нам свойствами. Но это будет "наш бизнес-объекти", а не "перечисление вообще", имхо. Может, конечно, просто пример цвета для этого неудачен — нужен более конкретный пример использования, который показал бы преимущества реализации н.н. 4 над другими, более простыми реализациями при использовании в данной конкретной задаче, но сейчас, имхо, тема как-то нераскрыта. Городить подобное только ради перечисленных задач кажется слегка тяжеловатым.

Очень полезным считаю раздел "Визуализация строгих перечислений" — за него отдельное спасибо!
Голь на выдумку хитра, однако...
Re[4]: Строгие перечисления в С++
От: unreg_flex  
Дата: 12.08.10 15:18
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>Я за рантайм. Ну не растут у нас лимоны, ну и фиг с ними, какой смысл их в горшочках выращивать... Разве что из спортивного интереса.

bnk>Сравним код выше с очевидным вариантом. Какой будет легче поддерживать? В общем, не доходят до меня пока эти изыски...

Я не люблю рантайм, но и буст мы не юзаем, я также считаю что хоть и авторы статьи потрудились на славу,
но увидев такое в коде какой нить юниор сразу поседеет, думаю не стоит так пужать людей =)

В коде когда нужно связать значение со строками или другими константными типами основная проблема на мой взгляд заключается в том, что объявлять перечисление нужно в заголовке, а соответствующий константный статический массив со значениями в cpp файле, из-за чего приходится при правке скакать по разным файлам и тщательно все проверять. Кроме того массив не контролируется при доступе. На этом потребности решения моих проблем по сути и заканчиваются.
Поэтому наваял давненько такой вот костылек которым успешно и пользуюсь:
#define BEGIN_STATIC_ARRAY(Name,Type) \
static Type Name(int index) { \
  static Type data[]={

#define END_STATIC_ARRAY() \
  }; \
  MESSAGE_ASSERT(index>=0&&index<ItemsNumber,"Некорректный индекс"); \
  MESSAGE_ASSERT(ItemsNumber==sizeof(data)/sizeof(data[0]),"Некорректное число элементов"); \
  return data[index]; \
}

#define BEGIN_STRING_LIST(Name) BEGIN_STATIC_ARRAY(Name,const char*)
#define END_STRING_LIST() END_STATIC_ARRAY()

Пример использования:

class A {

public:

  enum Some {
    Value0,
    Value1,
    Value2,
    ItemsNumber
  };

  // Обращаемся как A::EnglishValue(i)
  BEGIN_STRING_LIST(EnglishValue)
    "Value0",
    "Value1",
    "Value2",
  END_STRING_LIST()

  // Обращаемся как A::RussianValue(i)
  BEGIN_STRING_LIST(RussianValue)
    "Валуе0",
    "Валуе1",
    "Валуе2",
  END_STRING_LIST()

private:
  // ...
};


Допилить это по вкусу сможет каждый.

Свитч лучше всетаки не использовать, ибо например VS не всегда в состоянии сгенерить для вызова функции оптимальный код обращения к таблице, в этом варианте машинный код при отключенных ассертах в Release получается такой же как и с обычным статическим массивом (то есть никаких вызовов функции по сути нет), в итоге выходит, что все как бы и без рантайма.

Так выглядит код при обращении по неизвестному на стадии компиляции индексу (индекс в edi):
mov eax, DWORD PTR ?data@?1??RussianValue@A@@SAPBDH@Z@4PAPBDA[edi*4]
Re[2]: Строгие перечисления в С++
От: Igore Россия  
Дата: 13.08.10 07:01
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>Здравствуйте, Вьюков Д. С., Тепляков С. В., Вы писали:


ВДС>>Аннотация:

ВДС>>В данной статье рассмотрены несколько решений, позволяющих ослабить или практически полностью избавиться от недостатков перечислений (enumerations) языка программирования С++. Представленные решения, отличаются сложностью реализации и функциональностью, и могут оказаться полезными в арсенале каждого современного разработчика.

bnk>Вот честно не представляю, зачем может понадобиться что-то сложнее первого варианта, описанного в статье, кроме академических изысков

bnk>То есть, по мне, так вот это:

bnk>
bnk>enum Option
bnk>{
bnk>    Option_One, 
bnk>    Option_Two,

bnk>    Option_Count
bnk>}
bnk>

bnk>решает большинство задач встречающихся в народном хозяйстве,
bnk>включая автокомплит/именование и перечисление всех элементов (0 < i < Option_Count).
bnk>Ради чего плодить кучу безумных макросов??

bnk>Проблемы которые вижу со всеми остальными вариантами:

bnk>- Часто енумы используются как "флаги" ([Flags] в C#) , однако вариант (Option::One|Option::Two) не скомпилируется, нужен кастинг или еще экран кода с операторами "|".
bnk>- Такие енумы несовместимы с кодом на C, или с кодом на IDL.
bnk>- Для определения строготипизированного енума тупо придется писать больше неудобочитаемого текста.

bnk>Все IMHO, конечно


Мне вариант C# like больше нравится автодополнение быстрее сработает вроде как
namespace Option
{
   enum Enum
   {
      One,
      Two,
      Three
   }
};
Re[5]: Строгие перечисления в С++
От: March_rabbit  
Дата: 13.08.10 13:51
Оценка: +1
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, bnk, Вы писали:


bnk>>Я за рантайм. Ну не растут у нас лимоны, ну и фиг с ними, какой смысл их в горшочках выращивать... Разве что из спортивного интереса.

bnk>>Сравним код выше с очевидным вариантом. Какой будет легче поддерживать? В общем, не доходят до меня пока эти изыски...
bnk>>enum Option { Option_One, Option_Two, Option_Count };
V>Здесь можно забыть обновить Option_Count, если значения явно заданы для енума и не последовательно идут.
если значения идут не последовательно, то count не имеет смысла. Тогда уж Option_Max.
а для Option_Max можно воткнуть поближе к описанию енума что-либо вроде статического ассерта на тему Option_Two < Option_Max. Тогда добавление нового элемента не пройдет безнаказанным.
Re[6]: Строгие перечисления в С++
От: Vain Россия google.ru
Дата: 13.08.10 14:18
Оценка:
Здравствуйте, March_rabbit, Вы писали:

bnk>>>Я за рантайм. Ну не растут у нас лимоны, ну и фиг с ними, какой смысл их в горшочках выращивать... Разве что из спортивного интереса.

bnk>>>Сравним код выше с очевидным вариантом. Какой будет легче поддерживать? В общем, не доходят до меня пока эти изыски...
bnk>>>enum Option { Option_One, Option_Two, Option_Count };
V>>Здесь можно забыть обновить Option_Count, если значения явно заданы для енума и не последовательно идут.
M_>если значения идут не последовательно, то count не имеет смысла.
Здесь
Автор: Vain
Дата: 14.07.10
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.