Estoy escribiendo un envoltorio función generalizada, que puede envolver cualquier función en una llamada de estilo lua, que tiene la formafunciona como un argumento de plantilla, además de parámetro de plantilla variadic
int lua_function (lua_State * L)
Y me gustaría que la función de envoltura se genere sobre la marcha, así que estoy pensando en pasar la función como un argumento de plantilla. Esto es trivial si se conoce el número (por ejemplo, 2) de argumentos:
template <typename R, typename Arg1, typename Arg2, R F(Arg1, Args)>
struct wrapper
Sin embargo, no sé el número, por lo que pido para el argumento de plantilla variadic ayuda
// This won't work
template <typename R, typename... Args, R F(Args...)>
struct wrapper
El arriba no compilará, ya que el argumento variadico tiene que ser el último. Así que utilizo dos plantilla de nivel, la plantilla externa capta tipos, la plantilla interior capta la función:
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;
}
};
};
que funciona, excepto que para envolver una función como
double sin(double d) {}
el usuario tiene que escribir
func_type<decltype(sin)>::func<sin>::apply
que es tedioso. La pregunta es: ¿hay alguna forma mejor y más amigable para el usuario de hacerlo? (No puedo utilizar una plantilla de función para envolver todo el asunto, coz de un parámetro de función no puede ser utilizada como un argumento de plantilla.)
Creo que el puntero a la función puede ser un argumento de plantilla. Funciona al menos para MSVC. Se está resolviendo un problema similar al suyo aquí: http://stackoverflow.com/questions/4387971/c-pasar-metodo-de-metodo-por-template-argumento. –