Существующий макрос получает переменное число переменных в моем приложении.
Я хочу, используя этот макрос, напечатать эти переменные 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...);
}
Вы можете сделать это с небольшим количеством взлома. Хак не очень надежен, но он должен быть приемлемым, если вы используете его для отладки.
Идея состоит в том, чтобы упорядочить весь аргумент макроса переменной, а затем разделить последовательность меток, используя токены на запятых. Это требует, чтобы ни один из аргументов переменной не содержал запятую, что будет иметь место, если все они являются именами переменных, но не существует способа требовать этого, и фактически предложенный ниже код с радостью примет выражения, как показано.
#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 ++. Извиняюсь перед всеми, кто обиделся.
Вы не можете сделать это с помощью макросов. Вы могли бы использовать stringification для одной переменной ( do{
…}while(0)
полезно из-за этот).
#define MYPRINT(VarName) do{ \
std::cout << #VarName "=" << VarName << std::endl;} while(0)
затем используйте MYPRINT(x)
; Вы могли бы рассмотреть определение MYPRINT1
… MYPRINT19
(возможно, автоматически, через некоторый сценарий) для артик 1 — 19.
Если использовать недавний НКУ вы можете настроить его для своих целей, используя ПЛАВИТЬСЯ, но я считаю, что это не стоит усилий (вы потратите недели на это).
Вы можете рассмотреть возможность предварительной обработки вашего кода C ++ с помощью другого препроцессора (например, GPP) или какой-нибудь простой скрипт (например, awk
)