g ++ достаточно умен, чтобы оптимизировать рекурсивные вызовы шаблонных функций? - PullRequest
1 голос
/ 25 марта 2012

У меня есть этот фрагмент кода:

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 или что-то в этом роде.

1 Ответ

0 голосов
/ 21 апреля 2012

Я спросил в #gcc @ freenode.Они сказали да, если вы не берете указатель на локальные переменные функции.Но поскольку их нет, ответ должен быть да.

...