如何在c ++ 11中使用variadic模板参数递归获取variadic函数参数?

时间:2016-05-03 09:03:53

标签: c++11 lua

我正在使用C ++ 11开发自己的Lua引擎,我想编写一个函数包装器,它将具有可变参数的C ++函数注册到Lua环境。这在C ++ 0x中很简单,但很无聊因为我需要编写类似的代码来支持0~N参数的函数。 函数push用于将T推送到lua堆栈,其中函数upvalue_得到带有lua cclosure的C ++函数指针,并假设函数有两个参数T1和T2,T1是从lua堆栈获取索引为1,T2是从lua堆栈索引为2。

template <typename RVal, typename T1, typename T2>
struct functor<RVal,T1,T2>
{
    static int invoke(lua_State *L) 
    { 
        push(L,upvalue_<RVal(*)(T1,T2)>(L)(read<T1>(L,1),read<T2>(L,2))); 
        return 1; 
    }
};

template<typename T>
T upvalue_(lua_State *L)
{
    return user2type<T>::invoke(L, lua_upvalueindex(1));
}

使用C ++ 11,我编写了这样的代码片段:

template< typename RVal, typename ... ARGS>
struct functor
{
    static int invoke(lua_State* L)
    {
        typedef RVal (*FUNC_PTR)(ARGS...);
        FUNC_PTR f = upvalue_<FUNC_PTR>(L);
        push(L, f(read_stack<ARGS>(L)...));
        return 1;
    }
};

template<typename T>
T read_stack(lua_State* L)
{
    T t = read<T>(L, -1);
    lua_pop(L, 1);
    return t;
}

上面显示的代码可以工作,但参数顺序是相反的,因为read_stack始终从最后一个索引读取参数-1。 我的问题是如何从lua堆栈中读取参数从1到N(N等于sizeof ...(ARGS),如果ARGS不为空)具有可变参数模板参数并将它们传递给实际函数指针f以进行真正的调用?

2 个答案:

答案 0 :(得分:0)

不是特定于Lua,这里是一个通用的C ++ 11解决方案,用于将给定参数的顺序反转为函数。在下面的代码中,&#39;申请&#39;是我的示例目标函数(这里它只是根据其可变参数输出一些文本)。主要&#39;函数显示了辅助函数&#39; reverse_and_apply&#39;获取一个函数(或Functor精确)和一组参数,并使用一些模板技巧将给定函数应用于反向参数列表。注意我在这里有点肛门使用完美转发道歉,这在技术上是正确的,但遗憾的是在某种程度上混淆了代码。希望你得到主要信息。

setValue(int)

答案 1 :(得分:0)

您在C ++ 11中的代码甚至不起作用,因为未定义参数的评估顺序。 在C ++ 14中使用std::integer_sequence应该很容易。

示例代码:

template< typename RVal, typename... ARGS>
struct functor
{
    template <std::size_t... Is>
    static int invoke_impl(lua_State *L, std::index_sequence<Is...>)
    {
        typedef RVal (*FUNC_PTR)(ARGS...);
        FUNC_PTR f = upvalue_<FUNC_PTR>(L);
        push(L, f(read<ARGS>(L, Is)...));
        return 1;
    }

    static int invoke(lua_State* L)
    {
        return invoke_impl(L, std::index_sequence_for<ARGS...>{});
    }
};