У меня есть этот фрагмент кода:
template<typename... Args> class function_helper<void(Args...)>{
public:
typedef void(*generic_function)(Args...);
static void call(lua_State* l, generic_function func, Args... args){
func(args...);
}
template<typename... retrieved> static void call(lua_State* l, generic_function func, retrieved... read){
call(l, func, read..., to<typename std::tuple_element<sizeof...(read), std::tuple<Args...> >::type >(l, 1+sizeof...(read)));
}
static int wrapper(lua_State* l){
assert(lua_isuserdata(l, lua_upvalueindex(1)));
call(l, generic_function(lua_touserdata(l, lua_upvalueindex(1))));
return 0;
}
};
Цель состоит в том, чтобы иметь свободную функцию-обертку (со списком аргументов любой длины), чтобы ее можно было вызывать с помощью lua, нажав function_helper::wrapper
.
Все работает хорошо. Меня беспокоит то, что g ++ недостаточно умен, чтобы понять, что рекурсивные вызовы call
могут быть заменены одним вызовом, подобным
call(luastate, to<type1>(luastate, 1), to<type2>(luastate, 2), to<type3>(luastate, 3), ...);
Мой компилятор g ++ 4.6.1. Если у вас есть информация о g ++ 4.7 или новее, это также приветствуется.
P.S.
использование std::tuple
- это обходной путь ограничения g ++ 4.6, он не может распаковать список шаблонов vararg напрямую в аргумент vararg или что-то в этом роде.