Puis-je transmettre un pointeur de fonction "général" en tant qu'argument de modèle avec sa signature? Je sais que je peux passer la signature de fonction à un modèle:Pointeur de fonction en tant qu'argument modèle et signature
template<typename signature>
struct wrapper;
template<typename RT, typename... ATs>
struct wrapper<RT (ATs...)> {};
int f(int, double)
wrapper<decltype(f)> w;
Je peux aussi passer un pointeur de fonction comme un argument de modèle non type:
template<int (*pF)(int, double)> myTemp() {
pf(1, 1.0);
}
myTemp<f>();
Ce que je voudrais faire est quelque chose comme ceci
template<typename RT (*pF)(typename ATs...)>
Est-ce possible? Le pointeur de fonction doit être passé en tant qu'argument de modèle et ne doit pas être passé en tant que paramètre de fonction. Je souhaite utiliser le modèle pour envelopper les fonctions c et les rendre appelables à partir de lua. Le code suivant fonctionne (C++ 14, gcc, lua-5.3), mais pourrait être amélioré.
#include <iostream>
#include <type_traits>
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
using namespace std;
int add(int i, int j) {
cout << "adding " << i << " to " << j << "." << endl;
return i + j;
}
int sub(int i, int j) {
cout << "subtracting " << j << " from " << i << "." << endl;
return i - j;
}
// ****************************
template<typename signature>
struct wrapper;
template<typename RT, typename... ATs>
struct wrapper<RT (ATs...)> {
template<RT (*pF)(ATs...)>
void reg(lua_State *L, const char*n) {
auto lw = [](lua_State *L) -> RT {
lua_pushnumber(L, call<0>(pF, L));
return 1;
};
lua_pushcfunction(L, lw);
lua_setglobal(L, n);
}
template<int i, typename... ETs>
static
typename std::enable_if<i != sizeof...(ATs), RT>::type
call(RT (*f)(ATs...), lua_State *L, ETs... Es) {
auto arg = lua_tonumber(L, i+1);
return call<i+1>(f, L, Es..., arg);
}
template<int i, typename... ETs>
static
typename std::enable_if<i == sizeof...(ATs), RT>::type
call(RT (*f)(ATs...), lua_State *L, ETs... Es) {
return f(Es...);
}
};
#define regLua(L, fct, str) wrapper<decltype(fct)>().reg<fct>(L, str)
int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaL_dostring(L, "print(\"Hello World!\")");
// Ugly: add must be passed two times! Not a very userfriendly syntax.
wrapper<decltype(add)>().reg<add>(L, "add");
// Looks better, but uses a macro...
regLua(L, sub, "sub");
// optimal (but possible??):
// wrap<sub>(L, "sub");
luaL_dostring(L, "print(\"add:\", add(3, 5))");
luaL_dostring(L, "print(\"sub:\", sub(3, 5))");
lua_close(L);
return 0;
}
Je lis [pointeur _function comme modèle argument_] (http://stackoverflow.com/search ? q =% 5Bc% 2B% 2B% 5Donction + pointeur + as + modèle + paramètre) environ cinq à sept fois par semaine (si ce n'est plus souvent) ici. Bien sûr, vous ne pouvez pas trouver d'informations primaires, qui sont déjà disponibles? –
Je n'avais pas ce que 'myTemp()' est supposé être. Peut-être que vous manquez un type de retour? –
@ πάνταῥεῖ J'ai cherché le pointeur de fonction comme argument de modèle, mais tout ce que j'ai trouvé sont les deux premiers cas, et pas le troisième auquel je suis intéressé. Si vous avez un lien concernant ce cas, je serais reconnaissant. – Robin