有什么方法可以创建一个函数,该函数将成员函数或成员作为参数?

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

我有这样的功能:

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;
}

有什么方法可以创建一个函数,该函数将 成员函数 成员 作为参数来分解此代码?

(a,b,c,d和z不是同一类型)

是的,有。一种方法是将 void f 变成函数模板,然后将指针传递给所需数据成员或成员函数的成员,让 std::invoke (C++17, <functional> header) 做其余:

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);

当然,您应该将 T 替换为 Myglobal 的类型。 std::invoke 的好处是它会自动处理所有成员(数据或函数)。

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 .

template<typename... Mems>
void f(std::ofstream& ostrm, Mems&&... args)
{
    ((ostrm << std::invoke(args, Myglobal) << " "), ...);
}

并且您将一次性将所需的成员或成员函数传递给函数,而不是多次调用。

f(obj,
    &MyClass::m_data1, &MyClass::m_data2, &MyClass::m_data3,
    &MyClass::getData1, &MyClass::getData2, &MyClass::getData3);

(See live example)


并且在函数f中再提供一个模板参数(对于Class),你可以使它成为完全通用的代码,不需要全局变量。

template<typename Class, typename... Mems>
void f(std::ofstream& ostrm, const Class& obj, Mems&&... args)
//                           ^^^^^^^^^^^^^^^^
{
    ((ostrm << std::invoke(args, obj) << " "), ...);
}

现在在 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);