Я думаю, что если встречается ITERATION(ARGS)
, он принимает ITERATION_IMPL(hello, args(), world)
, заменяет args
на ARGS
, а затем выполняет повторное сканирование.ITERATION_IMPL(hello, ARGS(), world)
является вызовом ITERATION_IMPL
.Для этого он принимает ((p1),(p2),(p3),(p4))
и заменяет p2
на ARGS()
(вместе с другими параметрами).Затем он сканирует и разрешает ((hello),(a, b),(world),())
.Я не знаю, почему это работает, что он вызывает макрос с 4 параметрами с 3 аргументами в вашем случае.
Вы могли бы сделать
#define EVAL(X) X
#define ITERATION(args) ITERATION_IMPL EVAL((hello, args(), world))
Это заняло бы X
, подставило бы (hello, ARGS(), world)
, а затем повторило бы сканирование, в результате чего ARGS()
был бы заменен на a, b
.Получившаяся строка токена ITERATION_IMPL (hello, a, b, world)
сделает то, что вы ожидали
РЕДАКТИРОВАТЬ: протестировано с GCC:)
РЕДАКТИРОВАТЬ: я заметил, что вы хотите строку ((hello),(a),(b),(world))
, но мой ответ дает строку ITERATION_IMPL (hello, a, b, world)
.Я думаю, это потому, что когда он повторно просматривает после вызова ITERATION
, он заменяет IERATION_IMPL EVAL((hello, ARGS(), world))
на ITERATION_IMPL (hello, a, b, wold)
.Затем потребуется еще одно сканирование, чтобы заметить, что теперь он может вызывать ITERATION_IMPL
с этими аргументами.Таким образом, ITERATION
должно быть
#define ITERATION(args) EVAL(ITERATION_IMPL EVAL((hello, args(), world)))
Когда X
для внешнего EVAL
заменяется на ITERATION_IMPL EVAL((hello, args(), world))
, оно повторно просматривает и выдает ITERATION_IMPL (hello, a, b, world)
для вызова EVAL
.Затем он снова пересматривается для вызова ITERATION
и выдает последовательность, которую вы действительно хотели.