How to call a method for all non-null variables

Viewed 95

Given the following code:

class A {
    void DoStuff1(int x);
    void DoStuff2(float y);
    void DoStuff3(int a, float b);

    void DoStuff4(int c);
    void DoStuff4(float c);

    void ForEachChild(auto method);

    A* children[4];
}

So that within other methods I can call:

  • ForEachChild(DoStuff1(10));
  • ForEachChild(DoStuff2(5.0f));
  • ForEachChild(DoStuff3(15, 12.0f));
  • DoStuff4(...) overloading would be nice also, but not strictly needed

Or alternatively, if possible:

  • ForEachChild()->DoStuff1(10);
  • etc

ForEachChild() will iterate thru the children list and for each non-null pointer will call the method it was asked to call, with the variables that it simply forwards onward.

I have to do many things for all of the children and I'd rather not add a loop in all of those places, and I'd like to keep the code as readable as possible.

edit. Added the stuff about DoStuff3(), to make it clear that the methods number of parameters isn't fixed. And DoStuff4().

1 Answers

You could use a member-function template.

class A {
    void DoStuff1(int x);
    void DoStuff2(float y);

    template<typename... T, typename... U>
    void ForEachChild(void (A::*method)(T...), U&&... x){
         for(auto child : children)
            if(child) (child->*method)(std::forward<U>(x)...);
    }
    A* children[4];
}

And use as:

object.ForEachChild(&A::DoStuff1, 10);
object.ForEachChild(&A::DoStuff2, 3.1416);
object.ForEachChild(&A::DoStuff3, 3, 546.353);

object.ForEachChild(static_cast<void(A::*)(int)>(&A::DoStuff4), 3);
object.ForEachChild(static_cast<void(A::*)(float)>(&A::DoStuff4), 3);

Note that you require a cast to pass the the address of an overloaded function...

Demo

Related