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

2021-12-22 00:00:00 structure visual-c++ c++

考虑一个简单的结构:

struct abc{一个;字符 b;}

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

*a = [某个值]b = [某个字符]*

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

解决方案

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

您所要求的称为Reflection,即对象描述自身的能力.

由于元数据,大多数语言都可以实现反射.例如在 Python 中,对象的函数和属性存储在字典元素中.

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

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

如您的链接中所示,BOOST_FUSION_ADAPT_STRUCT 宏允许您采用标准的 struct 并为其提供所需的接口以被视为 Fusion.Sequence.>

另一个例子是使用 Fusion.VectorFusion.Map 来存储类的属性,然后将此 Sequence 暴露给自动打印/序列化/反序列化方法.

然而,这个系统有一个限制:元编程不能很好地与面向对象编程相结合.

struct Base { char a;};//适应结构派生:Base { char b;};//适应void print(Base const& b) { boost::fusion::for_each(b, Print());}

只会打印Base的成员(这里是a).使用多态时,您需要在某一点或另一点使用 virtual 方法:)

Consider a simple structure:

struct abc  
{  
    int a;  
    char b;  
}  

I got some value in a variable defined as its structure, and now I want to print the below.

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

What is the best way to achieve this for an arbitrary structure without having to write a dump...(...) function for each of the structure I encounter?

解决方案

It seems you already found the solution, but I'll expand a bit.

What you are calling for is called Reflection, i.e. the ability for an object to describe itself.

Most languages can implement reflection thanks to metadata. In Python for example, the functions and attributes of an object are stored in a dictionary element.

C++ does not have any native reflection system unlike C# or Java, which prevents (for example) this kind of automatic printing / serialization or deserialization.

However, C++ has very powerful metaprogramming support which allows us (through the use of templates) to emulate reflection (at compile-time). This is usually done using Boost.Fusion, a library meant for crossing over from compile-time to run-time.

As the example demonstrated in your link, the BOOST_FUSION_ADAPT_STRUCT macro allows you to take a standard struct and give it the required interface to be treated as a Fusion.Sequence.

Another example would be to use Fusion.Vector or Fusion.Map to store the attributes of the class and then expose this Sequence to automatic print/serialization/deserialization methods.

There is a limitation to this system however: Metaprogramming does not mesh well with OO-programming.

struct Base { char a; };            // Adapt
struct Derived: Base { char b; };   // Adapt

void print(Base const& b) { boost::fusion::for_each<Base>(b, Print()); }

will only print the member of Base (here a). When using polymorphism, you need to use virtual methods at one point or another :)

相关文章