我创建了一个MemberFunctionWrapper模板类,用于存储函数及其参数类型。它有一个调用方法,它接受void *的向量,并在调用函数之前将它们转换为函数调用所需的参数类型。
我的问题是包装器只能接受固定数量的函数参数
(_arg0,_arg1)。
我希望该类可以使用任意数量的函数参数(arg0,arg1,arg2 ... argX)如何实现这一目标?
提前致谢
class Foo
{
public:
void foo( int a, const string& b );
};
template< class _obj, class _function, class _arg0, class _arg1 >
class MemberFunctionWrapper
{
const _function m_memberfunction;
public:
MemberFunctionWrapper( _function memFn )
: m_memberfunction( memFn )
{ }
void call( std::shared_ptr<void>& obj,
const std::vector<std::shared_ptr<void>>& args )
{
m_memberfunction( *static_cast< _obj* >(obj.get()),
*static_cast< _arg0* >(args.at( 0 ).get()),
*static_cast< _arg1* >(args.at( 1 ).get()) );
}
};
int main()
{
std::shared_ptr<int> i( new int( 88 ) );
std::shared_ptr<string> s( new string( "hello" ) );
std::shared_ptr<Foo> foo( new Foo );
std::shared_ptr<void> iVoid = std::static_pointer_cast< void >(i);
std::shared_ptr<void> sVoid = std::static_pointer_cast< void >(s);
std::shared_ptr<void> fooVoid = std::static_pointer_cast< void >(foo);
MemberFunctionWrapper
<
Foo,
decltype(std::mem_fn( &Foo::foo )),
int,
string
> wrapper( &Foo::foo );
wrapper.call( fooVoid, std::vector<std::shared_ptr<void>>{iVoid, sVoid} );
system( "pause" );
}
答案 0 :(得分:0)
以下可能有所帮助:https://ideone.com/l7yAJN
template<typename F> class MemberFunctionWrapper;
template<class Obj, class Ret, typename ... Args>
class MemberFunctionWrapper<Ret (Obj::*)(Args...)>
{
typedef Ret (Obj::*MemberFunction)(Args...);
const MemberFunction m_memberfunction;
template <std::size_t ... Is>
void call(std::shared_ptr<void>& obj,
const std::vector<std::shared_ptr<void>>& args,
index_sequence<Is...>)
{
(static_cast<Obj*>(obj.get())->*m_memberfunction)
(*static_cast<typename std::remove_reference<Args>::type*>(args.at(Is).get())...);
}
public:
MemberFunctionWrapper(MemberFunction memFn) : m_memberfunction(memFn)
{}
void call(std::shared_ptr<void>& obj,
const std::vector<std::shared_ptr<void>>& args )
{
assert(args.size() == sizeof...(Args));
call(obj, args, make_index_sequence<sizeof...(Args)>());
}
};