Создайте переменный макрос / метод, который печатает имена и значения всех переменных

Существующий макрос получает переменное число переменных в моем приложении.
Я хочу, используя этот макрос, напечатать эти переменные name=value формат.

Вот небольшой пример:

#define EXISTING_MACRO(...) < ??? >

int main()
int a = 0;
int b = 1;
int c = 2;

EXISTING_MACRO(a,b,c);

Выход должен быть:

a=0, b=1, c=2

Я попытался сделать это, вызвав шаблонную функцию из макроса, и мне удалось вывести значения переменных, но не имена переменных. (#x печатает их адреса, и даже если это не так, то, вероятно, просто покажет имя переменной метода, 'f'):

#define SHOW(a) std::cout << #a << "=" << (a)

template<typename TF>
void write_err_output(std::ostream& out, TF const& f) {
out << f << std::endl;
}

template<typename TF, typename ... TR>
void write_err_output(std::ostream& out, TF const& f, TR const& ... rest) {
out << SHOW(f) << " ";
write_err_output(out, rest...);
}

2

Решение

Вы можете сделать это с небольшим количеством взлома. Хак не очень надежен, но он должен быть приемлемым, если вы используете его для отладки.

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

#define SHOW(...) show(std::cout, #__VA_ARGS__, __VA_ARGS__)

template<typename H1>
std::ostream& show(std::ostream& out, const char* label, H1&& value) {
return out << label << "=" << std::forward<H1>(value) << '\n';
}

template<typename H1, typename ...T>
std::ostream& show(std::ostream& out, const char* label, H1&& value, T&&... rest) {
const char* pcomma = strchr(label, ',');
return show(out.write(label, pcomma - label) << "="<< std::forward<H1>(value)
<< ',',
pcomma + 1,
std::forward<T>(rest)...);
}

(жить на coliru)

Для простоты и во избежание std::stringЯ использовал стандарт C strchr функция, а не функции библиотеки C ++. Извиняюсь перед всеми, кто обиделся.

6

Другие решения

Вы не можете сделать это с помощью макросов. Вы могли бы использовать stringification для одной переменной ( do{}while(0) полезно из-за этот).

#define MYPRINT(VarName) do{ \
std::cout << #VarName "=" << VarName << std::endl;} while(0)

затем используйте MYPRINT(x); Вы могли бы рассмотреть определение MYPRINT1MYPRINT19 (возможно, автоматически, через некоторый сценарий) для артик 1 — 19.

Если использовать недавний НКУ вы можете настроить его для своих целей, используя ПЛАВИТЬСЯ, но я считаю, что это не стоит усилий (вы потратите недели на это).

Вы можете рассмотреть возможность предварительной обработки вашего кода C ++ с помощью другого препроцессора (например, GPP) или какой-нибудь простой скрипт (например, awk)

2

По вопросам рекламы [email protected]