0

嗨,我想知道是否有人可以帮助我。我正在尝试实现 CallFunction (带有注释的位)。我不知道该怎么做。

[问题] 我想创建一个从 ...Arguments 创建的类型元组,但我想去掉限定符、const、& 等,这样我就可以用我的数据填充它并以某种方式传递给函数.

我现在不关心返回类型。有人指出我正确的方向或做过类似的事情吗?或者这完全是疯狂的,而不是可以做的事情。唔!无论如何 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}
};
4

1 回答 1

1

我假设,您的意思是用相应的索引分配值,而不是总是分配给0循环内的索引。假设您有一个实现(这是 C++14 的一部分),使用 a 的元素调用函数的基本方法std::tuple<...>相当简单:std::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));
}

基本思想是std::make_integer_sequence<...>创建一个合适的整数序列。一旦你得到这个,你还可以添加一个相应的操作,std::tuple<...>用基于你的值填充 a pState。实际填充的逻辑std::tuple<...>可能看起来像这样(我没有安装 Lua,即,我无法测试这是否真的有效,但类似这样的东西确实有效):

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 实现。实施相当简单。不过,这是一个使用不同名称实现必要的整数生成的实现。

于 2014-11-07T22:15:36.163 回答