上过课
struct {
int a1;
bool a2;
...
char* a500;
...
char a10000;
}
我想打印或流式传输
"a1 value is SOME_VALUE"
"a2 value is SOME_VALUE"
"a500 value is SOME_VALUE"
...
"a10000 value is SOME_VALUE"
成员变量的类型不相同(主要是int、bool、char*等,即不需要重载<< operator), and the member variable name could be named with anything, i.e., no rule to follow. Instead of typing explicitely one by one (very big tedious, and error-prone work), is there any generic way?
感谢您的任何评论!
你可以使用邪恶的宏:
#define DUMP(a) \
do { std::cout << #a " is value " << (a) << std::endl; } while(false)
使用示例(编辑现在更新了结构成员的示例):
#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;
}
在 CodePad 上观看实时 演示
a1 is value 3
a2 is value 3.14
a3 is value 03.1415926
s.a1 is value 3
s.a2 is value 3.14
s.a3 is value 03.1415926
回答未提出的问题。考虑一下如果将宏调用嵌套在条件循环或 for 循环中会发生什么情况。 Marshall Cline 解释了其余部分
watch
宏是有史以来最有用的技巧之一。
#define watch(x) cout << (#x) << " is " << (x) << endl
如果您正在调试代码,
watch(variable);
将打印变量的名称及其值。 (这是可能的,因为它是在预处理期间构建的。)
一个解决方法是使用自动代码生成。您将字段定义写入文件中,然后从中生成 .h 和 .cpp 文件。我将其用于包含大约 100 个带有大量字段的类的代码。它能够生成将它们发送到流(主要是调试)和套接字通信的代码。它非常可靠(无需测试任何这些功能),但由于它不是纯 C++,因此可能不是适合您的解决方案。
C++ 中没有办法枚举类的成员,因为 C++ 中没有反射。所以你无法访问变量名称。
void PrintMemberValue(int MyClass::*p, MyClass const & obj)
{
cout << "Member has value " << obj.*p;
}
MyClass obj;
int MyClass::*p = &MyClass::a1;
PrintMemberValue(p, obj);
p = &MyClass::a2;
PrintMemberValue(p, obj);
etc
GDB 可以打印结构。该脚本生成 gdb 脚本来设置断点并在 gdb_print 指定的位置打印值: