Вярвам, че заглавието се обяснява само по себе си, но ето един пример, който да илюстрира какво се опитвам да постигна:
#define PASTE2(_0, _1) _0 ## _1
#define DEFINE_OPS_FOR_TYPE(TYPE) \
int PASTE2(do_something_with_, TYPE)(void) { \
/* do_something_with_<TYPE> */ \
}
Всичко работи добре за char
, int
и типове с една дума, но когато става въпрос за типове unsigned
или други, които имат множество ключови думи, използването на поставяне на токени (a ## b
) не генерира валидно име поради интервала (напр.: do_something_with_foo bar
) .
Най-лесното решение, за което мога да се сетя, е да променя макроса DEFINE_OPS_FOR_TYPE
, за да вземе валидно име като втори параметър. Например:
#define DEFINE_OPS_FOR_TYPE(TYPE, NAME_FOR_TYPE) \
int PASTE2(do_something_with_, NAME_FOR_TYPE)(void) { \
/* do_something_with_<NAME_FOR_TYPE> */ \
}
Това работи според очакванията, но съм любопитен за други възможни решения, дори и да са прекалено сложни. Мислех да използвам _Generic
, но не виждам как ще помогне при дефинирането на име.
Сещате ли се за друго решение?
DEFINE_OPS_FOR_TYPE(unsigned, int)
иDEFINE_OPS_FOR_TYPE(unsinged, long, long)
? Мисля за#define DEFINE_OPS_FOR_TYPE(...)
и token-paste всички__VARGS__
за до 3 аргумента. Но се съмнявам, че е възможно. - person jweyrich   schedule 03.01.2013