Printing values of all fields in a C++ structure
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 开发者_StackOverflow社区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 :)
You need "reflection" to do this. Reflection is not provided natively in C++, or only for minimal informations (type ids/names).
There are libraries (like CAMP) that implement reflection features, so if you REALLY need reflection you should use one.
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.
The relevant library is Antony Polukhin's "magic_get". Specifically, it offers a "for each field" iteration mechanism, which takes a templated lambda with auto
parameter type. Example:
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.
There isn't one, not in C++. Tough luck.
If you're using C++ in .NET, you can potentially use the System.Reflection stuff to look at the innards of your structure. Unmanaged C++ rarely, if ever, stores that kind of metadata about objects, though.
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.
精彩评论