Я пишу обобщенную оболочку функций, которая может обернуть любую функцию в вызов типа lua, который имеет форму
int lua_function (lua_State * L)
И я хочу, чтобы функция-оболочка генерировалась "на лету", поэтому я думаю о передаче функции в качестве аргумента шаблона. Это тривиально, если вы знаете число (например, 2) аргументов:
template <typename R, typename Arg1, typename Arg2, R F(Arg1, Args)>
struct wrapper
Тем не менее, я не знаю числа, поэтому я прошу аргумент varadic template для справки
// This won't work
template <typename R, typename... Args, R F(Args...)>
struct wrapper
Вышеуказанное не будет компилироваться, поскольку переменный аргумент должен быть последним. Поэтому я использую двухуровневый шаблон, внешний шаблон захватывает типы, внутренний шаблон фиксирует функцию:
template <typename R, typename... Args>
struct func_type<R(Args...)>
{
// Inner function wrapper take the function pointer as a template argument
template <R F(Args...)>
struct func
{
static int call( lua_State *L )
{
// extract arguments from L
F(/*arguments*/);
return 1;
}
};
};
Это работает, за исключением того, что для обертывания функции типа
double sin(double d) {}
пользователь должен написать
func_type<decltype(sin)>::func<sin>::apply
который является утомительным. Вопрос в следующем: есть ли лучший, удобный для пользователя способ сделать это? (Я не могу использовать шаблон функции, чтобы обернуть все это, потому что параметр функции не может использоваться как аргумент шаблона.)