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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2758937/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:36:43  来源:igfitidea点击:

Printing values of all fields in a C++ structure

c++visual-c++structure

提问by Zhinkaas

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?

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

回答by Matthieu M.

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.

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

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.

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

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

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

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.

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

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

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

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

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

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 virtualmethods at one point or another :)

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

回答by Klaim

You need "reflection" to do this. Reflection is not provided natively in C++, or only for minimal informations (type ids/names).

你需要“反思”才能做到这一点。C++ 本身不提供反射,或者仅提供最少的信息(类型 ID/名称)。

There are libraries (like CAMP) that implement reflection features, so if you REALLY need reflection you should use one.

有一些库(如CAMP)实现了反射功能,所以如果你真的需要反射,你应该使用一个。

回答by JSB????

There isn't one, not in C++. Tough luck.

没有一个,不是在 C++ 中。倒霉。

回答by cHao

If you're using C++ in .NET, you can potentially use the System.Reflectionstuff to look at the innards of your structure. Unmanaged C++ rarely, if ever, stores that kind of metadata about objects, though.

如果您在 .NET 中使用 C++,您可以潜在地使用System.Reflection来查看结构的内部结构。不过,非托管 C++ 很少(如果有的话)存储关于对象的那种元数据。

回答by einpoklum

With C++17 (perhaps even C++14), and some crazy Russian hacks - it can be partially done. That is, you can print the types values in sequence, but you can't get the field names.

使用 C++17(甚至可能是 C++14)和一些疯狂的俄罗斯黑客 - 它可以部分完成。也就是说,您可以按顺序打印类型值,但无法获取字段名称。

The relevant library is Antony Polukhin's "magic_get". Specifically, it offers a "for each field" iteration mechanism, which takes a templated lambda with autoparameter type. Example:

相关的库是 Antony Polukhin 的"magic_get"。具体来说,它提供了“针对每个字段”的迭代机制,该机制采用具有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 << ' ';
    }
);

Answer migrated from a related/duplicate question - since somehow nobody mentioned this here.

答案从一个相关/重复的问题迁移而来 - 因为不知何故没有人在这里提到这一点。

回答by Ashutosh Singh

Just do this

就这样做

#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);
}

reflection is only required when the structs will be user defined and not by you and you are not sure about the internal structure of the struct.

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