2014-11-07 1 views
0

안녕하세요, 누구든지이 문제를 도와 줄 수 있는지 궁금합니다. CallFunction (주석이있는 비트)을 구현하려고합니다. 나는 그것을하는 방법에 대해 가야할지 모르겠다.데이터 튜플 생성 및 함수 arguements로 압축을 풀어 보내기

[질문] 생성 된 유형의 튜플을 만들고 싶습니다. 인수가 있지만 한정자, const, & 등을 제거하여 데이터로 채울 수 있습니다. 함수로 넘어 간다.

지금은 반환 유형으로 귀찮게하지 않습니다. 누구든지 올바른 방향으로 나를 가리키거나 비슷한 것을했을 수 있습니까? 아니면 완전히 미친 짓이 아닌 할 수있는 일입니다. HMM! 어쨌든 TY이 :) 그것을 확인하기위한

template <typename This, typename Func> class ForwardFunction 
{ 
private: 
    template <typename Object, typename Return, typename ...Arguments> struct info_base 
    { 
     enum { nargs = sizeof...(Arguments) }; 

     typedef Return return_type; 
     typedef std::tuple<Arguments...> arg_list_type; 

     template <size_t index> struct arg 
     { 
      typedef typename std::tuple_element<index, std::tuple<Arguments...>>::type type; 
     }; 

     template <int argCount> static void CallFunction(Func function, CLuaHelper & helper, lua_State *pState) 
     { 
      /* 
      // temp - pseudo 

      arg_list_type argList; 

      for (int i = 0; i < argCount; ++i) 
       std::get<0>(argList) = helper.Get<arg<i>::type>(pState); 

      (This::GetThis(pState)->*(function))(argList...); 
      */ 
     } 

     template <> static void CallFunction<0>(Func function, CLuaHelper & helper, lua_State *pState) 
     { 
      (This::GetThis(pState)->*(function))(); 
     } 

     static void Call(Func function, CLuaHelper & helper, lua_State *pState) 
     { 
      CallFunction<nargs>(function, helper, pState); 
     } 
    }; 

    template <typename Func> struct info; 
    template <typename Object, typename Return, typename ...Arguments> struct info<std::function<Return (Object::*)(Arguments...)>> : info_base<Object, Return, Arguments...> { }; 
    template <typename Object, typename Return, typename ...Arguments> struct info<std::function<Return (Object::*)(Arguments...) const>> : info_base<Object, Return, Arguments...> { }; 

public: 
    static int ForwardCall(Func function, lua_State *pState) 
    { 
     CLuaHelper helper(pState); 
     info<std::function<Func>>::Call(function, helper, pState); 
     return helper.ReturnValues(); 
    } 
}; 

자사가

#define __LUA_FUNCTION_CALL [&](lua_State *pState) -> int 

#define __LUA_INSTANT_ACCESS_CALL(name) \ 
    { #name, __LUA_FUNCTION_CALL { return ForwardFunction<CComponentScript, decltype(&CComponent::##name)>::ForwardCall(&CComponent::##name, pState); } } 

const CLuaHelper::function_list CComponentScript::m_sRegisterFunctions[] = 
{ 
    __LUA_INSTANT_ACCESS_CALL(SetOnLoad), 
    __LUA_INSTANT_ACCESS_CALL(SetOnEvent), 
    __LUA_INSTANT_ACCESS_CALL(SetOnUpdate), 
    __LUA_INSTANT_ACCESS_CALL(SetOnClose), 

    __LUA_INSTANT_ACCESS_CALL(RegisterEvent), 

    __LUA_INSTANT_ACCESS_CALL(SetBasePriority), 

    {nullptr, nullptr} 
}; 

답변

1

사용 당신이 해당 인덱스로 값을 할당하기보다는 항상 루프 내부의 0 인덱스에 할당하는 것을 의미, 가정합니다.

std::make_integer_sequence<...>가 생성
template <int... N, typename... T> 
void call_aux(std::integer_sequence<int, N...>, std::tuple<T...>&& value) 
{ 
    print(std::get<N>(value)...); 
} 

template <typename Tuple> 
void call(Tuple&& value) 
{ 
    call_aux(std::make_integer_sequence<int, std::tuple_size<std::decay_t<Tuple>>::value>(), 
      std::forward<Tuple>(value)); 
} 

기본적인 아이디어는 것을 : 기본적인 접근 방법은 (C++ (14)의 일부입니다) 당신이 std::integer_sequence의 구현이 아니라 정직하고 가정되는 std::tuple<...>의 요소와 함수를 호출합니다 정수의 적절한 순서. 이 작업을 완료하면 해당 작업을 추가하여 pState을 기반으로 한 값으로 std::tuple<...>을 채울 수 있습니다. 논리는 사실 (내가이 실제로 작동 여부를 테스트 할 수 없습니다, 즉, 루아가 설치되어 있지 않지만이 같은 일을 수행)에 std::tuple<...>이 같은 것을 볼 수 있었다 채우기 위해 : 코드 비록

template <int I, typename Tuple> 
bool assign_helper2(Tuple& tuple, lua_Helper& helper, lua_State* pState) { 
    std::get<I>(tuple) = helper.Get<arg<I>::type>(pState); 
} 
template <typename... T> 
void dummy(T&&...) { 
} 
template <int I, typename Tuple> 
void assign_helper1(std::integer_sequence<int, I...>, Tuple& tuple, 
        lua_Helper& helper, lua_State* pState) { 
    dummy(assign_helper2<I>(tuple, helper, pState)...); 
} 
template <typename Tuple> 
void assign(Tuple& tuple, lua_Helper& helper, lua_State* pState) { 
    assign_helper1(std::make_integer_sequence<int, std::tuple_size<std::decay_t<Tuple>>::value>(), 
        tuple, helper, pState); 
} 

C++ 14 기능을 사용하면 C++ 11을 사용하여 해당 클래스를 구현할 수 있습니다. 구현은 매우 간단합니다. Here is an implementation 다른 이름을 사용하여 필요한 정수 생성을 구현합니다.

+0

@ 피봇 : 예, 당신이 옳다고 생각합니다 (코드를 업데이트 할 것입니다). –

관련 문제