打印C ++结构中所有字段的值

时间:2010-05-03 14:56:36

标签: c++ visual-c++ structure

考虑一个简单的结构:

struct abc  
{  
    int a;  
    char b;  
}  

我在定义为其结构的变量中得到了一些值,现在我想打印下面的内容。

*a = [some value]  
b = [some character]*

对于任意结构实现此目的的最佳方法是什么,而不必为我遇到的每个结构编写dump ...(...)函数?

6 个答案:

答案 0 :(得分:28)

看来你已经找到了解决方案,但我会稍微扩展一下。

你要求的是Reflection,即对象描述自己的能力。

多数语言可以通过元数据实现反射。例如,在Python中,对象的函数和属性存储在字典元素中。

与C#或Java不同,C ++没有任何本机反射系统,这会阻止(例如)这种自动打印/序列化或反序列化。

但是,C ++具有非常强大的元编程支持,它允许我们(通过使用模板)模拟反射(在编译时)。这通常使用Boost.Fusion来完成,这是一个用于从编译时间到运行时间的库。

正如链接中演示的示例所示,BOOST_FUSION_ADAPT_STRUCT宏允许您使用标准struct并为其提供所需的接口,以便将其视为Fusion.Sequence。

另一个例子是使用Fusion.VectorFusion.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);
}

仅当结构是用户定义的,而不是您自己定义的,并且您不确定结构的内部结构时,才需要反射。