Дополнительные параметры с макросами C++

Есть ли некоторый способ получить дополнительные параметры с Макросами C++? Своего рода перегрузка была бы хороша также.

97
задан Ciro Santilli 新疆改造中心法轮功六四事件 20 June 2015 в 22:01
поделиться

7 ответов

Вот один способ сделай это. Он использует список аргументов дважды, сначала для формирования имени вспомогательного макроса, а затем для передачи аргументов этому вспомогательному макросу. Он использует стандартный прием для подсчета количества аргументов макроса.

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;
}

Это упрощает задачу для вызывающего макроса, но не для писателя.

140
ответ дан 24 November 2019 в 05:20
поделиться

На самом деле препроцессор не для этого.

Тем не менее, если вы хотите войти в область серьезного сложного макропрограммирования с минимальной удобочитаемостью, вам следует взглянуть на библиотеку препроцессора Boost . В конце концов, это не был бы C ++, если бы не было трех полностью совместимых с Тьюрингом уровней программирования (препроцессор, метапрограммирование шаблонов и базовый уровень C ++)!

3
ответ дан 24 November 2019 в 05:20
поделиться
#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)

В момент вызова вы знаете, сколько аргументов вы собираетесь передать, поэтому нет необходимости в перегрузке.

3
ответ дан 24 November 2019 в 05:20
поделиться

В зависимости от того, что вам нужно, вы могли бы сделать это с помощью var args с макросами. Теперь, необязательные параметры или перегрузка макросов, не существует.

0
ответ дан 24 November 2019 в 05:20
поделиться

gcc / g ++ поддерживает макросы varargs , но я не думаю, что это стандартно, поэтому используйте его на свой страх и риск.

6
ответ дан 24 November 2019 в 05:20
поделиться

Макросы C ++ не изменились по сравнению с C. Поскольку в C не было аргументов перегрузки и аргументов по умолчанию для функций, у него определенно не было их для макросов. Итак, чтобы ответить на ваш вопрос: нет, эти функции не существуют для макросов. Единственный вариант - определить несколько макросов с разными именами (или вообще не использовать макросы).

В качестве примечания: в C ++ обычно считается хорошей практикой максимально отказаться от макросов. Если вам нужны такие функции, есть большая вероятность, что вы злоупотребляете макросами.

33
ответ дан 24 November 2019 в 05:20
поделиться
#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 */
}

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: В основном безвредны.

5
ответ дан 24 November 2019 в 05:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: