Как большой поклонник ужасных макро-монстров, я хотел бы расширить ответ Джейсона Денга и сделать его действительно пригодным для использования. (К лучшему или к худшему.) Оригинал не очень хорош в использовании, потому что вам нужно модифицировать большой алфавитный суп каждый раз, когда вы хотите создать новый макрос, и еще хуже, если вам нужно другое количество аргументов.
Итак, я сделал версию с этими функциями:
- 0 аргумент работает
- от 1 до 16 аргументов без каких-либо изменений в грязной части
- Легко написать больше функций макроса
- Протестировано в gcc 10, clang 9, Visual Studio 2017
В настоящее время я только что сделал максимум 16 аргументов, но если вам нужно больше (действительно, сейчас? Вы просто становитесь глупыми ...), вы можете редактировать FUNC_CHOOSER и CHOOSE_FROM_ARG_COUNT, а затем добавить несколько запятых в NO_ARG_EXPANDER.
Пожалуйста, смотрите превосходный ответ Джейсона Денга для более подробной информации о реализации, но я просто оставлю код здесь:
#include <stdio.h>
void realCreate(int x, int y)
{
printf("(%d, %d)\n", x, y);
}
// This part you put in some library header:
#define FUNC_CHOOSER(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, ...) _f16
#define FUNC_RECOMPOSER(argsWithParentheses) FUNC_CHOOSER argsWithParentheses
#define CHOOSE_FROM_ARG_COUNT(F, ...) FUNC_RECOMPOSER((__VA_ARGS__, \
F##_16, F##_15, F##_14, F##_13, F##_12, F##_11, F##_10, F##_9, F##_8,\
F##_7, F##_6, F##_5, F##_4, F##_3, F##_2, F##_1, ))
#define NO_ARG_EXPANDER(FUNC) ,,,,,,,,,,,,,,,,FUNC ## _0
#define MACRO_CHOOSER(FUNC, ...) CHOOSE_FROM_ARG_COUNT(FUNC, NO_ARG_EXPANDER __VA_ARGS__ (FUNC))
#define MULTI_MACRO(FUNC, ...) MACRO_CHOOSER(FUNC, __VA_ARGS__)(__VA_ARGS__)
// When you need to make a macro with default arguments, use this:
#define create(...) MULTI_MACRO(CREATE, __VA_ARGS__)
#define CREATE_0() CREATE_1(0)
#define CREATE_1(x) CREATE_2(x, 0)
#define CREATE_2(x, y) \
do { \
/* put whatever code you want in the last macro */ \
realCreate(x, y); \
} while(0)
int main()
{
create();
create(10);
create(20, 20);
//create(30, 30, 30); // Compilation error
return 0;
}