在这种情况下,我需要一种方法将可变数量的参数传递给函数:
template<typename ...T>
struct Lunch
{
Lunch(T...){}
};
template<typename T>
T CheckLuaValue(lua_State* luaState,int index)
{
//Do Stuff
return value;
}
template <class MemberType, typename ReturnType, typename... Params>
struct MemberFunctionWrapper <ReturnType (MemberType::*) (Params...)>
{
static int CFunctionWrapper (lua_State* luaState)
{
ReturnType (MemberType::*)(Params...) functionPointer = GetFunctionPointer();
MemberType* member = GetMemberPointer();
int index = 1;
//Get a value for each type in Params
Lunch<Params...>
{
(CheckLuaValue<Params>(luaState,index), index++, void(), 0)...
};
CheckLuaValue为Params中的每种类型返回一个值。我的问题是我现在需要一种方法来调用我的函数所有这些值
member->*functionPointer(returnedLuaValues);
}
};
我将如何做到这一点?
答案 0 :(得分:2)
所以我偷了一些Luc Danton对sFuller和Pubby(关于序列)的序列建议,我生成了这个“停止与operator,
版本混淆”的版本:
#include <iostream>
struct lua_State {};
template<typename T>
T CheckLuaValue( int n, lua_State* l)
{
std::cout << "arg[" << n << "] gotten\n";
return T(n);
}
template<int ...>
struct seq { };
// generates a seq< First, ..., Last-1 > as "type"
template<int First, int Last>
struct gen_seq
{
template<int N, int... S>
struct helper : helper<N-1, N-1, S...> {};
template<int... S>
struct helper<First, S...> {
typedef seq<S...> type;
};
typedef typename helper<Last>::type type;
};
template< typename X >
struct MemberFunctionWrapper;
template< typename F >
struct MemberFunctionHelper
{
typedef F MethodPtr;
};
template<class InstanceType, typename ReturnType, typename... Params>
struct MemberFunctionWrapper< ReturnType(InstanceType::*)(Params...) >
{
typedef MemberFunctionHelper<ReturnType(InstanceType::*)(Params...)> Helper;
typedef typename Helper::MethodPtr MethodPtr;
static MethodPtr& GetFunctionPointer() {static MethodPtr pFunc; return pFunc;}
static InstanceType*& GetMemberPointer() {static InstanceType* pThis;return pThis;}
template<int n, typename Param>
static auto GetLuaValue( lua_State* luaState )->decltype(CheckLuaValue<Param>(n,luaState))
{
return CheckLuaValue<Param>(n,luaState);
}
template< typename sequence >
struct call;
template< int... I >
struct call<seq<I...>>
{
ReturnType operator()( lua_State* luaState, InstanceType* instance, MethodPtr method ) const
{
return (instance->*method)( GetLuaValue<I,Params>( luaState )... );
}
};
static int CFunctionWrapper( lua_State* luaState)
{
MethodPtr func = GetFunctionPointer();
InstanceType* instance = GetMemberPointer();
ReturnType retval = call< typename gen_seq< 1, sizeof...(Params)+1 >::type >()( luaState, instance, func );
return 0;
}
};
struct test{ int foo(int x, double d){std::cout << "x:" << x << " d:" << d << "\n";}};
int main(){
typedef MemberFunctionWrapper< int(test::*)(int, double) > wrapper;
test bar;
wrapper::GetFunctionPointer() = &test::foo;
wrapper::GetMemberPointer() = &bar;
wrapper::CFunctionWrapper(0);
}
现在,请注意,对CheckLuaValue的调用可能是乱序的(即,它可以在arg 1之前从Lua请求arg 2),但是右边的那个将被传递给右边的参数。
以下是测试运行:http://ideone.com/XVmQQ6
答案 1 :(得分:1)
如果我理解正确,你应该改变定义Lunch
来调用成员函数指针:
template <class MemberType, typename ReturnType, typename... Params>
struct MemberFunctionWrapper <ReturnType (MemberType::*) (Params...)>
{
template<typename ...T>
struct foo // new Lunch
{
foo(ReturnType (MemberType::*)(Params...) functionPointer, MemberType* member, T... args){
member->*functionPointer(args...);
}
};
static int CFunctionWrapper (lua_State* luaState)
{
ReturnType (MemberType::*)(Params...) functionPointer = GetFunctionPointer();
MemberType* member = GetMemberPointer();
int index = 1;
//member->*(bindedMemberFunction->memberFunction);
//Get a value for each type in Params
foo<Params...>
{
functionPointer,
member,
(++index, CheckLuaValue<Params>(luaState,index))...
};
}
};