如果你願意寫出讓其他開發者哭泣的「調皮」代碼,那麼是的。試試這個:
#define ENUM(name, ...) typedef enum { M_FOR_EACH(ENUM_IDENTITY, __VA_ARGS__) } name; \
char * name ## _DEBUGSTRINGS [] = { M_FOR_EACH(ENUM_STRINGIZE, __VA_ARGS__) };
#define ENUM_IDENTITY(A) A,
#define ENUM_STRINGIZE(A) #A,
ENUM(MyEnum,
foo, bar, baz, boo
)
你顯然需要一個for-each宏來完成這個工作。這裏有一個簡單的一個:
#define M_NARGS(...) M_NARGS_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define M_NARGS_(_10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
#define M_CONC(A, B) M_CONC_(A, B)
#define M_CONC_(A, B) A##B
#define M_FOR_EACH(ACTN, ...) M_CONC(M_FOR_EACH_, M_NARGS(__VA_ARGS__)) (ACTN, __VA_ARGS__)
#define M_FOR_EACH_0(ACTN, E) E
#define M_FOR_EACH_1(ACTN, E) ACTN(E)
#define M_FOR_EACH_2(ACTN, E, ...) ACTN(E) M_FOR_EACH_1(ACTN, __VA_ARGS__)
#define M_FOR_EACH_3(ACTN, E, ...) ACTN(E) M_FOR_EACH_2(ACTN, __VA_ARGS__)
#define M_FOR_EACH_4(ACTN, E, ...) ACTN(E) M_FOR_EACH_3(ACTN, __VA_ARGS__)
#define M_FOR_EACH_5(ACTN, E, ...) ACTN(E) M_FOR_EACH_4(ACTN, __VA_ARGS__)
#define M_FOR_EACH_6(ACTN, E, ...) ACTN(E) M_FOR_EACH_5(ACTN, __VA_ARGS__)
#define M_FOR_EACH_7(ACTN, E, ...) ACTN(E) M_FOR_EACH_6(ACTN, __VA_ARGS__)
#define M_FOR_EACH_8(ACTN, E, ...) ACTN(E) M_FOR_EACH_7(ACTN, __VA_ARGS__)
#define M_FOR_EACH_9(ACTN, E, ...) ACTN(E) M_FOR_EACH_8(ACTN, __VA_ARGS__)
#define M_FOR_EACH_10(ACTN, E, ...) ACTN(E) M_FOR_EACH_9(ACTN, __VA_ARGS__)
這應該是顯而易見如何擴展該循環有更長的上限,但是......這個答案空間的考慮。只要您願意將額外的迭代複製並粘貼到該位,循環可能會持續下去。
對於非調試構建,請使用#ifdef選擇ENUM版本而不使用第二行。
編輯:從teppic偷指定initialisers想法,這裏是一個更可怕的版本,也有非有序初始化器值的工作原理:
#define ENUM(name, ...) typedef enum { M_FOR_EACH(ENUM_ENAME, __VA_ARGS__) } name; \
char * name ## _DEBUGSTRINGS [] = { M_FOR_EACH(ENUM_ELEM, __VA_ARGS__) };
#define ENUM_ENAME(A) M_IF(M_2ITEMS(M_ID A), (M_FIRST A = M_SECOND A), (A)),
#define ENUM_ELEM(A) M_IF(M_2ITEMS(M_ID A), ([M_FIRST A] = M_STR(M_FIRST A)), ([A] = M_STR(A))),
#define M_STR(A) M_STR_(A)
#define M_STR_(A) #A
#define M_IF(P, T, E) M_CONC(M_IF_, P)(T, E)
#define M_IF_0(T, E) M_ID E
#define M_IF_1(T, E) M_ID T
#define M_2ITEMS(...) M_2I_(__VA_ARGS__, 1, 0)
#define M_2I_(_2, _1, N, ...) N
#define M_FIRST(A, ...) A
#define M_SECOND(A, B, ...) B
#define M_ID(...) __VA_ARGS__
ENUM(MyEnum,
foo, bar, baz, boo
)
ENUM(NotherEnum,
A, B, (C, 12), D, (E, 8)
)
我不能保證你的人身安全,如果你在其他人必須維護的代碼中使用這種類型的東西。
據我所知,沒有辦法做到這一點,就像你所做的一樣,沒有寫自己的方法。 – 2013-03-05 22:11:57
不幸的是,這是不可能的,因爲枚舉名稱在編譯之後不可用。 – iDev 2013-03-05 22:22:09
[將objective-c typedef轉換爲其字符串等效項]的可能重複(http://stackoverflow.com/questions/1094984/convert-objective-c-typedef-to-its-string-equivalent)。您可以使用其中一種建議的方法。 – iDev 2013-03-05 22:22:36