制作打印所有变量名称和值的可变参数宏/方法

Make variadic macro / method which prints all variables names and values

现有宏在我的应用程序中获取可变数量的变量。
我想使用这个宏,以 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...);
}

你不能用宏来做到这一点。您可以使用 stringification for a single variable (the do{...}while(0) is useful because of this).

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

然后使用MYPRINT(x);您可以考虑为 arities 1 到 19 定义 MYPRINT1 ... MYPRINT19 (也许是自动的,通过一些脚本)。

如果使用最近的 GCC you might customize it for your purposes using MELT,但我认为这不值得付出努力(您将花费数周时间)。

您可能会考虑使用其他一些预处理器(例如 gpp)或一些简单的脚本(例如 awk)预处理您的 C++ 代码

您可以通过一些技巧来完成此操作。该 hack 不是很可靠,但如果您将它用于调试目的,它应该是可以接受的。

想法是将整个可变宏参数字符串化,然后通过逗号标记化将标签序列分开。这要求可变参数的 none 包含一个逗号,如果它们都是变量名就会出现这种情况,但没有办法要求这一点,事实上下面建议的代码将很乐意接受表达式,如图所示.

#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++ 库函数。对任何被冒犯的人表示歉意。