Fra*_*ale 7 c++ templates member member-functions c++17
我有一个这样的功能:
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;
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以创建将成员函数或成员分解为代码的函数作为参数?
(a,b,c,D和z不同类型的)
就在这里。一种方法是void f变成函数模板,然后将指针传递给所需数据成员或成员函数的成员,然后让std::invoke(C ++ 17,<functional>标头)完成其余工作:
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);
Run Code Online (Sandbox Code Playgroud)
当然,您应该用课程T类型代替Myglobal。有趣的std::invoke是它会自动处理所有成员(数据或函数)。
该@lubgr 解释使用std::invoke。一步可以整个代码行减少到一行,使用倍的表达从C ++ 17。
template<typename... Mems>
void f(std::ofstream& ostrm, Mems&&... args)
{
((ostrm << std::invoke(args, Myglobal) << " "), ...);
}
Run Code Online (Sandbox Code Playgroud)
并且您将一次将所需的成员或成员函数传递给该函数,而不是多次调用。
f(obj,
&MyClass::m_data1, &MyClass::m_data2, &MyClass::m_data3,
&MyClass::getData1, &MyClass::getData2, &MyClass::getData3);
Run Code Online (Sandbox Code Playgroud)
(请参见现场示例)
并且在函数中f为提供了另一个模板参数(用于Class),您可以使其成为完全通用的代码,而无需全局变量。
template<typename Class, typename... Mems>
void f(std::ofstream& ostrm, const Class& obj, Mems&&... args)
// ^^^^^^^^^^^^^^^^
{
((ostrm << std::invoke(args, obj) << " "), ...);
}
Run Code Online (Sandbox Code Playgroud)
现在在 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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
246 次 |
| 最近记录: |