Я пытаюсь определить структуру C ++ с переменными членами макросом как часть системы метаданных самоанализа. Учитывая, что я создаю определение структуры, я не могу использовать шаблоны времени компиляции (верно?). Вместо этого я создаю макрос с переменным числом аргументов, который должен принимать кортежи (тип, имя), но у меня возникли проблемы при написании макроса, который будет расширяться и соединять кортеж с символом, чтобы получить что-то вроде
JOIN(.,(a,A)) -> a.A
или JOIN(&,(b,B)) -> b&B
.
Я работаю в Visual Studio 2017, и часть моей путаницы может заключаться в несоответствии в расширении VA_ARGS в MSVC и GCC: Расширение MSVC ++ с переменным макросом
Мой подход состоял в том, чтобы написать макрос для распаковки, который просто удаляет скобки из кортежа, и макрос соединения, который бы соединял аргументы по желаемой строке:
#define UNPACK(a, b) a, b
#define JOINAB(a, b, S) a S b
#define JOINTUPLE(S, ab) JOINAB(UNPACK ab, S)
Но это не такработать, как кажется, макрос не оценивается в правильном порядке. Затем я попытался явно расширить аргументы, например #define EXPAND(args) args
, но безуспешно.
Наконец-то я нашел обходной путь, вставив скобку аргумента в распаковку, тем самым «форсируя» порядок вычисления:
#define EXPAND(...) __VA_ARGS__
#define UNPACK(a, b) (a, b
#define JOINAB(a, b, S) a S b
#define JOINTUPLE(S, ab) EXPAND(JOINAB UNPACK ab, S))
, который работает, но кажется очень хакерским ...
Мои вопросы
- Есть ли правильный способ оценки неупакованного результата? ?
- Зачем мне РАСШИРЯТЬСЯ? Без него выражение
JOINTUPLE(:,(a,B))
преобразуется в JOIN (a, B, :)
, но почему это не обрабатывается далее до a : B
? - Может ли быть способ решить это с помощью оператора вставки токена?
S
существует только в 3 вариантах.