Вопрос

Я работаю с библиотекой, которая включает в себя набор препроцессорных библиотек. Один из них представляет собой макрос в стиле For_each, который итерации по поводу генеракодицетагкода и вызывает пользовательский макрос для каждого аргумента. Показанный пользователь MACRO называется: __VA_ARGS__

Тем не менее, проблема в том, что она работает только с предоставленными пользователем макросами, которые принимают аргумент Single . Я пытаюсь сделать что-то особенное, которое включает как название генеракодицетагкода, так и каждое поле в структуре. Проблема в том, что это требует двух аргументов макроса.

Поскольку библиотека, с которой я работаю, принимает только одинарный макрос, есть ли способ «привязать» дополнительный аргумент для моего макроса?

Сейчас я должен жесткокодировать имя структуры в моем макросе. Итак, если SOME_MACRO(current_arg) я работаю с именем struct, я должен сказать:

#define MY_MACRO(FIELD) /* do something with &Foo::FIELD */
.

Есть ли что-нибудь, что я мог бы «привязать» второй аргумент struct к макросу, возможно, с некоторой дальнейшей косметикой, чтобы, когда библиотека вызывает мой макрос, он сможет расширить как:

#define MY_MACRO(FIELD) /* do something with &STRUCT::FIELD */
.

Это было полезно?

Решение

Да.Вы можете использовать следующую технику.

#define MY_MACRO(FIELD) EXPAND FIELD
#define EXPAND(X, FIELD) X::FIELD()
.

Использование в следующем тестовом коде:

struct foo { static int f() { return 0; } };
struct STRUCT { static int f() { return 1; } };

#define MY_MACRO(FIELD) EXPAND FIELD
#define EXPAND(X, FIELD) X::FIELD()

int main ()
{
  int i = MY_MACRO((STRUCT,f)); // see here braces inside braces
}
.

выше код расширяется до,

int main ()
{
  int i = STRUCT::f();
}
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top