Я считаю, что название говорит само за себя, но вот пример, иллюстрирующий то, что я пытаюсь сделать:
#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(...)
и токен-вставке всех__VARGS__
до 3 аргументов. Но я сомневаюсь, что это возможно. - person jweyrich   schedule 03.01.2013