Search code examples
c++templatesc++17membermember-functions

Is there any way to create a function that takes as argument a member function or a member?


I have a function like this:

void f(std::ofstream& ostrm)
{
    auto a = Myglobal->getData1();
    ostrm << a;

    auto b = Myglobal->getData2();
    ostrm << b;

    auto c = Myglobal->m_data1;
    ostrm << c;

    auto d = Myglobal->m_data2;
    ostrm << d;

    //...
    auto z = Myglobal->getData1000();
    ostrm << z;
}

Is there any way to create a function that takes as argument a member function or a member to factorize this code?

(a, b, c, d and z are not the same type)


Solution

  • Yes, there is. One way is to turn void f into a function template, then pass the pointer to member of the desired data member or member function and let std::invoke (C++17, <functional> header) do the rest:

    template <class PtrToMember>
    void f(std::ofstream &ostrm, PtrToMember m){
        ostrm << std::invoke(m, Myglobal);
    }
    
    // call like this:
    
    f(someStream, &T::getData1);
    f(someStream, &T::m_data1);
    

    where you should replace T by the the type of Myglobal of course. The nice thing about std::invoke is that it automatically handles all member (data or functions).