0

I have a struct like this one:

struct Player {
POINT3D headPosition;
POINT3D position;
POINT2D view;
INT32 health;
// etc...
};

And I would like to iterate through the members of this struct to do some actions, a bit like we could do with foreach in some other languages.

Is there any way I could do something like that in C++? My research indicate that it is not possible natively, I found that it could be possible with some library like Boost.Hana, but I would like to be sure first that there is absolutely no other ways without a third party library. Even something with macros or generated at compilation time would do. Since we know exactly the struct it has to be automatable somehow. You can ignore the problems related to different data types for my issue, in the "foreach" loop I will give the member variable to a template function that accepts all types of variables found in that struct.

Thank you for your help on this matter.

Pierre Ciholas
  • 169
  • 3
  • 12
  • 2
    No native reflection in C++, you have to rely on some external library asboost hana. – Jarod42 Apr 10 '18 at 17:37
  • 1
    There is currently no way to natively iterate over the members of a struct. There are some proposals for metaclasses that would support this feature, but currently it is not possible without some meta information about your struct. (Look at Qt or the like). – callyalater Apr 10 '18 at 17:37
  • https://github.com/apolukhin/magic_get might kelp. – Jarod42 Apr 10 '18 at 17:43
  • Boost.Hana is a header-only library for C++. The duplicate refers to another Boost reflection solution. Something from Boost is your best option. – jacknad Apr 10 '18 at 17:49

1 Answers1

3

Yes, this is possible, using insane Russian hacks :-)

The relevant library is Antony Polukhin "magic get". Specifically, it offers a "for each field" 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 << ' ';
    }
);

Caveat: This requires C++14 or even C++17 to work!

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • you can also write a genuine struct iterator with that library. – user1095108 Apr 11 '21 at 14:47
  • @user1095108: It wouldn't be a "genuine" iterator, because an iterator has to have a single value type, but sort of, yes. – einpoklum Apr 11 '21 at 16:20
  • well, I needed it, so [here](https://github.com/user1095108/generic/blob/master/structiterator.hpp) it is. It could be made more generic, if some kind of a reference wrapper were used. – user1095108 Apr 11 '21 at 22:37