考虑一个简单的结构:
struct abc
{
int a;
char b;
}
我在定义为其结构的变量中得到了一些值,现在我想打印下面的内容。
*a = [some value]
b = [some character]*
对于任意结构实现此目的的最佳方法是什么,而不必为我遇到的每个结构编写dump ...(...)函数?
答案 0 :(得分:28)
看来你已经找到了解决方案,但我会稍微扩展一下。
你要求的是Reflection
,即对象描述自己的能力。
多数语言可以通过元数据实现反射。例如,在Python中,对象的函数和属性存储在字典元素中。
与C#或Java不同,C ++没有任何本机反射系统,这会阻止(例如)这种自动打印/序列化或反序列化。
但是,C ++具有非常强大的元编程支持,它允许我们(通过使用模板)模拟反射(在编译时)。这通常使用Boost.Fusion来完成,这是一个用于从编译时间到运行时间的库。
正如链接中演示的示例所示,BOOST_FUSION_ADAPT_STRUCT
宏允许您使用标准struct
并为其提供所需的接口,以便将其视为Fusion.Sequence。
另一个例子是使用Fusion.Vector
或Fusion.Map
来存储类的属性,然后将此Sequence公开给自动打印/序列化/反序列化方法。
然而,该系统存在一个局限性:元编程与OO编程并不完美。
struct Base { char a; }; // Adapt
struct Derived: Base { char b; }; // Adapt
void print(Base const& b) { boost::fusion::for_each<Base>(b, Print()); }
只会打印Base
的成员(此处为a
)。使用多态时,您需要在某一时刻使用virtual
方法:)
答案 1 :(得分:3)
你需要“反思”才能做到这一点。反射不是在C ++中本地提供的,或者仅用于最小的信息(类型ID /名称)。
有些库(如CAMP)实现了反射功能,所以如果你真的需要反射,你应该使用反射功能。
答案 2 :(得分:2)
没有一个,不是C ++。好运。
答案 3 :(得分:0)
如果您在.NET中使用C ++,则可以使用System.Reflection内容来查看结构的内部结构。但是,非托管C ++很少(如果有的话)存储关于对象的那种元数据。
答案 4 :(得分:0)
使用C ++ 17(甚至可能是C ++ 14)和一些疯狂的俄罗斯黑客 - 它可以部分完成。也就是说,您可以按顺序打印类型值,但无法获取字段名称。
相关图书馆是Antony Polukhin的"magic_get"。具体来说,它为每个领域提供了一个&#34;&#34;迭代mechanism,它采用带有auto
参数类型的模板化lambda。例如:
struct simple {
int a;
char b;
short d;
};
simple x {42, 'a', 3};
std::stringstream ss;
boost::pfr::for_each_field(
x,
[&ss](auto&& val) {
ss << val << ' ';
}
);
从相关/重复的问题迁移回答 - 因为在这里没有人提到过这个问题。
答案 5 :(得分:0)
只需执行
#include<iostream>
using namespace std;
struct abc
{
int a;
char b;
};
void display(abc myStruct){
cout << "struct abc {"<< endl;
cout << abc.a << endl;
cout << abc.b << endl;
cout << "}" << endl;
}
int main(){
abc myStruct
display(myStruct);
}
仅当结构是用户定义的,而不是您自己定义的,并且您不确定结构的内部结构时,才需要反射。