Is there any way to create a function that takes as argument a member function or a member?
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).
The @lubgr has explained the use of std::invoke
. One step further you can reduce the entire lines of code to a single line, using fold expression from c++17.
template<typename... Mems>
void f(std::ofstream& ostrm, Mems&&... args)
{
((ostrm << std::invoke(args, Myglobal) << " "), ...);
}
and you will pass the desired members or member functions to the function at once, instead of calling many times.
f(obj,
&MyClass::m_data1, &MyClass::m_data2, &MyClass::m_data3,
&MyClass::getData1, &MyClass::getData2, &MyClass::getData3);
(See live example)
And providing one more template parameter in the function f
(for the Class
), you can make it completely generic code and no global variables needed.
template<typename Class, typename... Mems>
void f(std::ofstream& ostrm, const Class& obj, Mems&&... args)
// ^^^^^^^^^^^^^^^^
{
((ostrm << std::invoke(args, obj) << " "), ...);
}
and now in the main()
std::ofstream ostrm{"test_file.txt"};
const auto obj{ std::make_unique<MyClass>() };
f(ostrm,
obj,
&MyClass::m_data1, &MyClass::m_data2, &MyClass::m_data3,
&MyClass::getData1, &MyClass::getData2, &MyClass::getData3);