如何将对象及其方法转换为仅使用方法参数可调用的函数
How to convert an object and its method into a function callable just with method’s arguments
有函数
template<typename Class, typename MemberFuncPtr>
auto makeCallback( Class* a, MemberFuncPtr func )
{
return [a, func]( auto&&... args )
{
return ( a->*func )( std::forward<decltype( args )>( args )... );
};
}
将对象指针及其成员方法转换为捕获它们的 lambda,以后只需使用方法的参数即可调用。
它工作正常,除了一种情况,其中该方法是虚拟的并且在派生的 class 中被覆盖,例如
#include <iostream>
struct Base
{
virtual void g( int, int ) const
{
std::cout << "Base" << std::endl;
}
};
struct Derived : Base
{
virtual void g( int, int ) const override
{
std::cout << "Derived" << std::endl;
}
};
template<typename Class, typename MemberFuncPtr>
auto makeCallback( Class* a, MemberFuncPtr func )
{
return [a, func]( auto&&... args )
{
return ( a->*func )( std::forward<decltype( args )>( args )... );
};
}
int main()
{
Derived d;
auto cb = makeCallback( &d, &Base::g );
cb( 1, 2 );
return 0;
}
这里尽管 makeCallback( &d, &Base::g )
程序打印“Derived”。
有没有办法只修改 makeCallback
(包括对其签名的任何更改)以在程序输出中接收“Base”?
你可能会做一些改变:
template<typename Class, typename MemberFuncPtr>
auto makeCallback( Class* a, MemberFuncPtr func )
{
return [a, func]( auto&&... args )
{
return std::invoke(func, a, std::forward<decltype( args )>( args )... );
};
}
int main()
{
Derived d;
auto cb = makeCallback(&d, [](auto obj, auto&&... args){ obj->Base::g(args...); });
cb( 1, 2 );
}
有函数
template<typename Class, typename MemberFuncPtr>
auto makeCallback( Class* a, MemberFuncPtr func )
{
return [a, func]( auto&&... args )
{
return ( a->*func )( std::forward<decltype( args )>( args )... );
};
}
将对象指针及其成员方法转换为捕获它们的 lambda,以后只需使用方法的参数即可调用。 它工作正常,除了一种情况,其中该方法是虚拟的并且在派生的 class 中被覆盖,例如
#include <iostream>
struct Base
{
virtual void g( int, int ) const
{
std::cout << "Base" << std::endl;
}
};
struct Derived : Base
{
virtual void g( int, int ) const override
{
std::cout << "Derived" << std::endl;
}
};
template<typename Class, typename MemberFuncPtr>
auto makeCallback( Class* a, MemberFuncPtr func )
{
return [a, func]( auto&&... args )
{
return ( a->*func )( std::forward<decltype( args )>( args )... );
};
}
int main()
{
Derived d;
auto cb = makeCallback( &d, &Base::g );
cb( 1, 2 );
return 0;
}
这里尽管 makeCallback( &d, &Base::g )
程序打印“Derived”。
有没有办法只修改 makeCallback
(包括对其签名的任何更改)以在程序输出中接收“Base”?
你可能会做一些改变:
template<typename Class, typename MemberFuncPtr>
auto makeCallback( Class* a, MemberFuncPtr func )
{
return [a, func]( auto&&... args )
{
return std::invoke(func, a, std::forward<decltype( args )>( args )... );
};
}
int main()
{
Derived d;
auto cb = makeCallback(&d, [](auto obj, auto&&... args){ obj->Base::g(args...); });
cb( 1, 2 );
}