В Java перечисления имеют несколько возможностей, отсутствующих в перечислениях C/C++. Я хотел бы иметь возможность определять перечисления с, скажем, с помощью макроса ENUM(Color, Red, Green, Blue)
или ENUM(Color, {Red, Green, Blue})
или что-то не так, и иметь перечисление, определенное этими возможностями, каким-то образом реализовано.Автоматизация добавления Java-enum-подобных возможностей для перечисления
В частности, я хотел бы быть в состоянии сделать следующее:
for (Color p : Color::values()) { }
и
Color color(Red);
cout << "My face shone a bright " << color;
и
Color color = valueOf<Color>("Green");
/* ... */
cout << "It ain't easy being " << color;
Примечания:
- Бонусные баллы, если решение позволяет мне указать (интегральное) значение для каждого значения перечисления (например, Красный - 2, зеленый - 5, синий - 19).
- Бонусные баллы, если решение позволяет мне указать «унаследованный тип», а-ля
enum Color : unsigned char { Red, Green, Blue};
- Предложения с использованием подталкивание приветствуются, хотя я предпочел бы придерживаться только в стандартной библиотеке.
- Я не «женат» на макросах.
- Этот вопрос относится к this one, но это не то же самое. Этот вопрос касается главным образом разрешения нескольких полей данных, в то время как я не забочусь об этом и доволен надлежащим перечислением одного типа.
Прежде всего, +1 наверняка :-) Теперь, вы можете объяснить значение нескольких определений evalN? Мне не совсем понятно, что они делают. В более общем плане вы, кажется, выполняете какой-то магический трюк, чтобы понять, что в C/C++ нет рекурсивных '# define'. Не могли бы вы подробнее рассказать об этом? – einpoklum
Ну, просто чтобы быть ясным, лично я по-прежнему предпочитаю другое решение с несколькими макросами. Это решение очень сложно, и я считаю, что он не будет работать со всеми реализациями препроцессора. Грубая идея заключается в том, что «mapc» выполняет один шаг рекурсивного отображения. «eval» - это простая идентификация, однако каждый раз, когда вызывается макрос, он выполняет макрораспределение своего аргумента, поэтому делает еще один шаг вложенной (рекурсивной) оценки. Многие вложенные оценки будут выполнять множество (рекурсивных) расширений и оценивать выражение на достаточной глубине. – Marian
Дело в том, что вы комбинируете вложение evalN + 1 в evalNs, но также вставляете вызовы evalN внутри друг друга ('eval3 (eval3 (eval3 (... (eval3 (__ VA_ARGS __))))) почему это необходимо? – einpoklum