Ответ 1
#define ESC(...) __VA_ARGS__
затем
MY_MACRO( ESC(A<int, double>), text );
может делать то, что вы хотите.
Никакой запятой не разрешено в аргументе макроса, потому что это будет рассматриваться как несколько аргументов, и препроцессинг будет неправильным. Однако мы можем заключить в скобки аргумент, чтобы препроцессор рассматривал его как один аргумент. Есть ли макрос или другие методы, которые могут удалить заключенные круглые скобки?
Например, если я определяю макрос как
#define MY_MACRO(a, b) ...
и используйте его как
MY_MACRO( A<int, double>, text );
будет неправильным. используйте его как
MY_MACRO( (A<int, double>), text)
с макросом или техникой для удаления круглых скобок будет отлично. Boost предоставляет макрос BOOST_IDENTITY_TYPE
только для типов, но не для общих случаев
#define ESC(...) __VA_ARGS__
затем
MY_MACRO( ESC(A<int, double>), text );
может делать то, что вы хотите.
Этот макро-трюк похож на решение Якка, но устраняет необходимость явно передавать в другой макрос в качестве параметра.
#include <stdio.h>
#define _Args(...) __VA_ARGS__
#define STRIP_PARENS(X) X
#define PASS_PARAMETERS(X) STRIP_PARENS( _Args X )
int main()
{
printf("without macro %d %d %d %d %d %d\n", (5,6,7,8,9,10) ); // This actually compiles, but it WRONG
printf("with macro %d %d %d %d %d %d\n", PASS_PARAMETERS((5,6,7,8,9,10)) ); //Parameter "pack" enclosed in parenthesis
return 0;
}
Конечно, вы могли бы стать творческим, сделав макрос PASS_PARAMETERS в переменный макрос и передав несколько пакетов параметров.
Простым взломом может быть использование переменных массивов:
#define MY_MACRO(a, b...) ...
Затем вы можете использовать его как:
MY_MACRO(text, A<int, double>)
Запятая во втором аргументе по-прежнему интерпретируется как разделитель аргументов (это означает, что макрос фактически вызывается с тремя аргументами), но он расширяется внутри макроса, делая поведение одинаковым. Однако переменный аргумент должен быть последним в макросе.