Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Iterating through all of an object's members?

Tags:

c++

boost

Suppose I have an object with many members:

class Example {
    AnotherClass member1;
    AnotherClass member2;
    YetAnotherClass member3;
    ...
};

Is there a short/concise way to do something like:

foreach(member m: myExample)
    m.sharedMethod();

Instead of accessing each one individually?

I think I could put them in a vector and use a shared_ptr for the same effect, I was just wondering if say, Boost or some other popular library doesn't have something to do this automatically.

like image 352
vvv Avatar asked Aug 22 '11 02:08

vvv


People also ask

What are iterators in C++?

The most obvious form of an iterator is a pointer. A pointer can point to elements in an array and can iterate through them using the increment operator (++). But, all iterators do not have similar functionality as that of pointers.

How do you iterate through an array of objects?

The most obvious form of an iterator is a pointer. A pointer can point to elements in an array and can iterate through them using the increment operator (++).

How do you iterate through a variable in Python?

Take a variable and check its type. If the type is an Object, iterate through its properties. If the type is an Array, iterate through its values. If the type is a string/number, process it. This function might need to execute itself, depending on how many layers of nested logic it encounters.

How many types of iterators are there in Python?

The whole list is as given below: Types of iterators: Based upon the functionality of the iterators, they can be classified into five major categories: Input Iterators: They are the weakest of all the iterators and have very limited functionality.


2 Answers

C++ does not support class introspection, so you cannot iterate over all of the members in a class like that - not without having a (manually written) function that iterates over all members for you anyway.

You could, in principle, add a template member like so:

template<typename Functor>
void doAllMembers(Functor &f) {
  f(member1);
  f(member2);
  f(member3);
}

That said, I would regard this as a broken design; you've gone and exposed all of your internal members publicly. What happens if you add one later? Or change the semantics of one? Make one a cached value that's sometimes out of date? etc. Moreover, what happens if you have members which don't all inherit from the same types?

Step back and reconsider your design.

like image 123
bdonlan Avatar answered Oct 07 '22 11:10

bdonlan


There are several solutions to this issue, contrary to what the naysayers blabber, but no built-in way.

C++ support a limited kind of introspection, at compile-time: you can check the template parameters.

Using either Boost.Tuple or Boost.Fusion (for its map), you can indeed achieve what you wish. In Boost.Fusion you even have BOOST_FUSION_ADAPT_STRUCT to transform a basic structure into a Fusion Sequence (and thus iterate it).

It requires quite a bit of template meta-programming though.

like image 23
Matthieu M. Avatar answered Oct 07 '22 11:10

Matthieu M.