Есть ли некоторый способ получить дополнительные параметры с Макросами C++? Своего рода перегрузка была бы хороша также.
Вот один способ сделай это. Он использует список аргументов дважды, сначала для формирования имени вспомогательного макроса, а затем для передачи аргументов этому вспомогательному макросу. Он использует стандартный прием для подсчета количества аргументов макроса.
enum
{
plain = 0,
bold = 1,
italic = 2
};
void PrintString(const char* message, int size, int style)
{
}
#define PRINT_STRING_1_ARGS(message) PrintString(message, 0, 0)
#define PRINT_STRING_2_ARGS(message, size) PrintString(message, size, 0)
#define PRINT_STRING_3_ARGS(message, size, style) PrintString(message, size, style)
#define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
#define PRINT_STRING_MACRO_CHOOSER(...) \
GET_4TH_ARG(__VA_ARGS__, PRINT_STRING_3_ARGS, \
PRINT_STRING_2_ARGS, PRINT_STRING_1_ARGS, )
#define PRINT_STRING(...) PRINT_STRING_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
int main(int argc, char * const argv[])
{
PRINT_STRING("Hello, World!");
PRINT_STRING("Hello, World!", 18);
PRINT_STRING("Hello, World!", 18, bold);
return 0;
}
Это упрощает задачу для вызывающего макроса, но не для писателя.
На самом деле препроцессор не для этого.
Тем не менее, если вы хотите войти в область серьезного сложного макропрограммирования с минимальной удобочитаемостью, вам следует взглянуть на библиотеку препроцессора Boost . В конце концов, это не был бы C ++, если бы не было трех полностью совместимых с Тьюрингом уровней программирования (препроцессор, метапрограммирование шаблонов и базовый уровень C ++)!
#define MY_MACRO_3(X,Y,Z) ...
#define MY_MACRO_2(X,Y) MY_MACRO(X,Y,5)
#define MY_MACRO_1(X) MY_MACRO(X,42,5)
В момент вызова вы знаете, сколько аргументов вы собираетесь передать, поэтому нет необходимости в перегрузке.
В зависимости от того, что вам нужно, вы могли бы сделать это с помощью var args с макросами. Теперь, необязательные параметры или перегрузка макросов, не существует.
gcc
/ g ++
поддерживает макросы varargs , но я не думаю, что это стандартно, поэтому используйте его на свой страх и риск.
Макросы C ++ не изменились по сравнению с C. Поскольку в C не было аргументов перегрузки и аргументов по умолчанию для функций, у него определенно не было их для макросов. Итак, чтобы ответить на ваш вопрос: нет, эти функции не существуют для макросов. Единственный вариант - определить несколько макросов с разными именами (или вообще не использовать макросы).
В качестве примечания: в C ++ обычно считается хорошей практикой максимально отказаться от макросов. Если вам нужны такие функции, есть большая вероятность, что вы злоупотребляете макросами.
#include <stdio.h>
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#define PP_CONCAT(a,b) PP_CONCAT_(a,b)
#define PP_CONCAT_(a,b) a ## b
#define THINK(...) PP_CONCAT(THINK_, PP_NARG(__VA_ARGS__))(__VA_ARGS__)
#define THINK_0() THINK_1("sector zz9 plural z alpha")
#define THINK_1(location) THINK_2(location, 42)
#define THINK_2(location,answer) THINK_3(location, answer, "deep thought")
#define THINK_3(location,answer,computer) \
printf ("The answer is %d. This was calculated by %s, and a computer to figure out what this"
" actually means will be build in %s\n", (answer), (computer), (location))
int
main (int argc, char *argv[])
{
THINK (); /* On compilers other than GCC you have to call with least one non-default argument */
}
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: В основном безвредны.