Как бы я «генерировать переменные параметры»?

Мне нужен способ передать переменное количество параметров функции в следующих условиях:

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

}
};

Как бы я поступил так?

2

Решение

Так что я украл некоторые из советов по последовательностям Люка Дантона для 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 2 от Lua до arg 1), но правильный аргумент будет передан правильному аргументу.

Вот тестовый прогон: http://ideone.com/XVmQQ6

2

Другие решения

Если я правильно понимаю, вы должны изменить определение 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))...
};
}
};
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector