Здравствуйте, Vain, Вы писали:
V>Здравствуйте, rsdntchkru, Вы писали:
V>>>>>... V>>>>>Можно ещё наворотов добавить, вроде итератора по значениям енума (через boost::mpl) и перегрузить операторы, чтобы делать операции над значениями енума. R>>>>ужос! это пример как из простого сделать нечитабельно-неподдерживаемое сложное? V>>>Вы вариант remark'а видели? Так ещё больший ужос, лучше вам в программирование нос не совать, там много ужософ ходят.. R>>Да уж, наверно надо было не совать. К сожалению как 17 лет назад засунул, так все там. И все еще не перстаю порой удивляться ширине пытливой мысли некоторых программистов типа как приведенной в варианте 4 этой статьи. Если из обычного enuma такую тему можно было развить, то что будет если они код для пузырьковой сортировки опишут? Роман на 500 листов V>Не будет романов, std::sort решает в большинстве, похоже за 17 лет вы не в курсе про него
Не удивлюсь если напишут. А вы, я уверен, придумаете на это еще более изощренный вариант
Здравствуйте, Вьюков Д. С., Тепляков С. В., Вы писали:
ВДС>В данной статье рассмотрены несколько решений, позволяющих ослабить или практически полностью избавиться от недостатков перечислений (enumerations) языка программирования С++. Представленные решения, отличаются сложностью реализации и функциональностью, и могут оказаться полезными в арсенале каждого современного разработчика.
Мне трепетно возражать истинным гуру, но по моему скромному мнению уже за это:
switch(c.GetValue())
{
//Использовать выражение Color::Red().GetValue() в блоках
//case нельзя, т.к. это выражение не является константой
//времени компиляции.
//Специально для этой цели внутри каждого класса
//определяется внутреннее перечисление, которое содержит
//все значения констант с завершающим символом "_"case Color::Red_:
std::cout << "Hello, Red color!" << std::endl;
break;
}
Весь вариант 4 можно смело отправлять в раздел специальных решений под конкретную бизнес-задачу. Причем условия этой бизнес задачи прямо указаны в статье:
Вариант 4. Строгое перечисление
Это наиболее функциональный, но и наиболее сложный в реализации вариант, который позволяет следующее:
...
Цитировать весь текст не буду, но по-моему решается как раз очень конкретная задача, к общему "типу перечислений и использованию" отношения прямо не имеющая. И это, имхо, правильно. При необходимости оперировать в пространстве задачи неким "специальным типом перечисления" его и следует создавать и оперировать им как специальным нашим бизнес-объектом с нужными нам свойствами. Но это будет "наш бизнес-объекти", а не "перечисление вообще", имхо. Может, конечно, просто пример цвета для этого неудачен — нужен более конкретный пример использования, который показал бы преимущества реализации н.н. 4 над другими, более простыми реализациями при использовании в данной конкретной задаче, но сейчас, имхо, тема как-то нераскрыта. Городить подобное только ради перечисленных задач кажется слегка тяжеловатым.
Очень полезным считаю раздел "Визуализация строгих перечислений" — за него отдельное спасибо!
Здравствуйте, bnk, Вы писали:
bnk>Я за рантайм. Ну не растут у нас лимоны, ну и фиг с ними, какой смысл их в горшочках выращивать... Разве что из спортивного интереса. bnk>Сравним код выше с очевидным вариантом. Какой будет легче поддерживать? В общем, не доходят до меня пока эти изыски...
Я не люблю рантайм, но и буст мы не юзаем, я также считаю что хоть и авторы статьи потрудились на славу,
но увидев такое в коде какой нить юниор сразу поседеет, думаю не стоит так пужать людей =)
В коде когда нужно связать значение со строками или другими константными типами основная проблема на мой взгляд заключается в том, что объявлять перечисление нужно в заголовке, а соответствующий константный статический массив со значениями в cpp файле, из-за чего приходится при правке скакать по разным файлам и тщательно все проверять. Кроме того массив не контролируется при доступе. На этом потребности решения моих проблем по сути и заканчиваются.
Поэтому наваял давненько такой вот костылек которым успешно и пользуюсь:
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):
Здравствуйте, bnk, Вы писали:
bnk>Здравствуйте, Вьюков Д. С., Тепляков С. В., Вы писали:
ВДС>>Аннотация: ВДС>>В данной статье рассмотрены несколько решений, позволяющих ослабить или практически полностью избавиться от недостатков перечислений (enumerations) языка программирования С++. Представленные решения, отличаются сложностью реализации и функциональностью, и могут оказаться полезными в арсенале каждого современного разработчика.
bnk>Вот честно не представляю, зачем может понадобиться что-то сложнее первого варианта, описанного в статье, кроме академических изысков 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 больше нравится автодополнение быстрее сработает вроде как
Здравствуйте, 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. Тогда добавление нового элемента не пройдет безнаказанным.
Здравствуйте, March_rabbit, Вы писали:
bnk>>>Я за рантайм. Ну не растут у нас лимоны, ну и фиг с ними, какой смысл их в горшочках выращивать... Разве что из спортивного интереса. bnk>>>Сравним код выше с очевидным вариантом. Какой будет легче поддерживать? В общем, не доходят до меня пока эти изыски... bnk>>>enum Option { Option_One, Option_Two, Option_Count }; V>>Здесь можно забыть обновить Option_Count, если значения явно заданы для енума и не последовательно идут. M_>если значения идут не последовательно, то count не имеет смысла. Здесь