Search code examples
c++c++11std-functionstdbind

Call any object member function on a list of objects using std::function


I have a list of objects where I need to call a member function - no big deal so far: iterate through the list, make that call - done.

Now I have various places that almost do the same on the same list, except that the called member function changes (argument is always the same, a double value).

I tried around a bit with std::function, but in the end can't get it working. Any suggestions? (I'm back to C++ after many years of C#, so forgot a lot).

This is how it looks now:

void CMyService::DoSomeListThingy(double myValue)
{
    for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
    {
        (*v_Iter)->MethodToBeCalled(myValue);
    }
}

void CMyService::DoSomeThingDifferent(double myValue)
{
    for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
    {
        (*v_Iter)->CallTheOtherMethod(myValue);
    }
}

And this is how I'd prefer it:

void CMyService::DoSomeListThingy(double myValue)
{
    ApplyToList(&CMyListItem::MethodToBeCalled, myValue);
}

void CMyService::DoSomeThingDifferent(double myValue)
{
    ApplyToList(&CMyListItem::CallTheOtherMethod, myValue);
}

void CMyService::ApplyToList(std::function<void(double)> func, double myValue)
{
    for (std::list<CMyListItem*>::iterator v_Iter = myList.begin(); v_Iter != myList.end(); ++v_Iter)
    {
        (*v_Iter)->func(myValue);
    }
}

Solution

  • void CMyService::ApplyToList(void (CMyListItem::*func)(double), double myValue) {
        for (auto p : myList) {
            (p->*func)(myValue);
        }
    }
    

    With pre-C++11 compilers:

    void CMyService::ApplyToList(void (CMyListItem::*func)(double), double myValue) {
      for (std::list<CMyListItem*>::iterator v_Iter = myList.begin();
           v_Iter != myList.end(); ++v_Iter) {
        ((*v_Iter)->*func)(myValue);
      }
    }