在c ++中打印变量名的通用方法

pep*_*ero 8 c++ variables printf iostream

给一堂课

struct {
  int a1;
  bool a2;
  ...
  char* a500;
  ...
  char a10000;      
}
Run Code Online (Sandbox Code Playgroud)

我想打印或流出

"a1 value is SOME_VALUE"  
"a2 value is SOME_VALUE"
"a500 value is SOME_VALUE"
...
"a10000 value is SOME_VALUE"
Run Code Online (Sandbox Code Playgroud)

成员变量的类型不一样(主要是int,bool,char*等,也就是说,不需要重载<<运算符),成员变量名可以用任何东西命名,即没有遵循的规则.而不是逐个明确地输入(非常繁琐且容易出错的工作),有没有通用的方法?

谢谢你的评论!

seh*_*ehe 14

你可以使用一个邪恶的宏:

#define DUMP(a) \
    do { std::cout << #a " is value " << (a) << std::endl; } while(false)
Run Code Online (Sandbox Code Playgroud)

用法示例(编辑现在使用struct成员的示例更新):

#include <iostream>

#define DUMPSTR_WNAME(os, name, a) \
    do { (os) << (name) << " is value " << (a) << std::endl; } while(false)

#define DUMPSTR(os, a) DUMPSTR_WNAME((os), #a, (a))
#define DUMP(a)        DUMPSTR_WNAME(std::cout, #a, (a))

struct S {
    int a1;
    float a2;
    std::string a3;

    std::ostream& dump(std::ostream& os)
    {
        DUMPSTR(os, a1);
        DUMPSTR(os, a2);
        DUMPSTR(os, a3);
        return os;
    }
};

int main()
{
    S s = { 3, 3.14, "  03.1415926" };

    s.dump(std::cout);

    DUMP(s.a1);
    DUMP(s.a2);
    DUMP(s.a3);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

查看CodePad上的现场演示

为什么有趣的宏?

回答未提出的问题.考虑如果将宏调用嵌套在条件循环或for循环中会发生什么.Marshall Cline解释了其余部分


unw*_*ind 9

您正在寻找的功能通常称为反射.它不是C++的一部分,因为在编译语言中,您所追求的信息(人类可读的变量名称)通常不会被编译器保留.运行代码不需要它,因此包含它没有意义.

为了这个目的,调试器通常可以检查带外符号信息或保存在二进制文件中的符号数据,以显示这样的名称,但为此目的重新执行可能更多的工作而不是它的价值.

我建议你自己寻找一些许多"技巧"(=解决方案)来实现它.


Agi*_*gle 5

watch宏是有史以来最有用的技巧之一。

#define watch(x) cout << (#x) << " is " << (x) << endl
Run Code Online (Sandbox Code Playgroud)

如果您正在调试代码,watch(variable);将打印变量的名称及其值。(这是可能的,因为它是在预处理期间构建的。)