Препроцессор C, макрос "Перегрузка" - PullRequest
4 голосов
/ 06 августа 2010

Я пытаюсь сделать что-то вроде макроса "Перегрузка", чтобы MACRO (что-то) расширялось иначе, чем MACRO (что-то, еще).

Используя фрагмент, полученный из здесь (я не уверен, что он на 100% переносим) и некоторые функции из библиотеки Boost PP, я смог заставить его работать: D

//THESE TWO COUNT THE NUMBER OF ARGUMENTS
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)

//THIS ONE RETURNS THE PARAMETER AT POSITION _i FROM A LIST OF __VA_ARGS__
#define VA_ARG(_i, ...) BOOST_PP_ARRAY_ELEM(_i, (VA_NARGS(__VA_ARGS__), (__VA_ARGS__)))

//AND THIS ONE IS THE 'OVERLOADED' MACRO ;)
#define TEST(...) BOOST_PP_IF(BOOST_PP_EQUAL(1, VA_NARGS(__VA_ARGS__)), function_A(VA_ARG(0, __VA_ARGS__)), \ //1 parameter
                  BOOST_PP_IF(BOOST_PP_EQUAL(2, VA_NARGS(__VA_ARGS__)), function_B(VA_ARG(0, __VA_ARGS__) + VA_ARG(1, __VA_ARGS__)), \ //2 parameters
                  BOOST_PP_IF(BOOST_PP_EQUAL(3, VA_NARGS(__VA_ARGS__)), function_C(VA_ARG(1, __VA_ARGS__) + VA_ARG(2, __VA_ARGS__)), BOOST_PP_EMPTY())) // 3 parameters and so on ...

So       TEST(a) = function_A(a)
      TEST(a, b) = function_B(a + b)
   TEST(a, b, c) = function_C(b + c)

Теперь мне все еще не хватает двух других вещей, которые я хочу сделать:

  1. (Это мне безразлично, если я никогда не решу это) Я считаю, что MACRO может быть написано так, что при получении числа «вариантов» и его соответствующего «вывода» генерируется код, подобный тот, что выше. Что-то вроде TEMPLATE (3, function_A (...), function_B (...), function_C (...)) для генерации примера выше.

  2. Что происходит, когда TEST () вызывается без аргументов? Ну, VA_NARGS расширяется до 1. Но первый аргумент "" (ничего). Я пытаюсь найти способ либо обнаружить «нулевые» аргументы в __VA_ARGS__, либо провести различие между «нулевым» и реальным аргументом, чтобы расширить функцию «перегрузки», чтобы реагировать на эту ситуацию. Есть идеи?

1 Ответ

5 голосов
/ 06 августа 2010

Чтобы ответить на ваш вопрос 2 в первую очередь.Да, с помощью переменных макросов также можно обнаружить пустой список аргументов.Объяснение немного длинное, я написал это здесь .Должно быть относительно легко объединить этот подход с используемыми вами макросами повышения.

Для вашего вопроса 1 да, это также возможно.Я думаю, что в Boost есть несколько макросов итераторов, которые очень близки к этому, но они выглядят немного пугающими.Если я правильно понимаю, вы должны использовать что-то вроде вложенных списков (a, (b, (c,d))), что не слишком удобно.

(я написал набор макросов, которые могут достичь этого более напрямую, но, к сожалению, пакет еще не готов к выпускуСвяжитесь со мной в частном порядке, если вы действительно заинтересованы в этом.)

Редактировать: Пакет P99 опубликован в то же время исодержит много вещей над макросом "перегрузка" и набирает универсальные макросы.

...