Ich versuche, jede Funktion in eine Funktion, die ein Argument (State Interpreter) dauert, zu wickeln. Und wenn ich die Funktion direkt übergebe, funktioniert alles gut. Aber wenn ich in eine zusätzliche Funktion einbinden, bekomme ich einen Compilerfehler. Erklären Sie bitte, was mache ich falsch.Template-Funktion Wrapper
#include <iostream>
template <std::size_t... Is>
struct _indices {
template <template <size_t...> class Receiver>
using Relay = Receiver<Is...>;
};
template <std::size_t N, std::size_t... Is>
struct _indices_builder : _indices_builder<N-1, N-1, Is...> {};
template <std::size_t... Is>
struct _indices_builder<0, Is...> {
using type = _indices<Is...>;
};
struct lua_State
{};
template <typename Ret, typename... Args>
struct FunctionWrapperImpl {
template <size_t... Indices>
struct ImplementationNonVoid {
template <Ret (* func)(Args...)> static inline
int invoke(lua_State* state) {
func(10);
return 1;
}
};
using Implementation =
typename _indices_builder<sizeof...(Args)>::type::template Relay<
ImplementationNonVoid
>;
};
template <typename ToBeWrapped>
struct Wrapper {
};
template <typename Ret, typename... Args>
struct Wrapper<Ret (*)(Args...)>:
FunctionWrapperImpl<Ret, Args...>::Implementation {};
int test(int a)
{
std::cout<< a;
return 5;
}
typedef int (*lua_CFunction) (lua_State *L);
template <typename T>
lua_CFunction register_func(T fun)
{
lua_CFunction f =
(&Wrapper<decltype (fun)>::template invoke<T>); // Error
// no matches converting function 'invoke' to type 'lua_CFunction {aka int (*)(struct lua_State*)}'
//do somthing with f
return f;
}
int main(int argc, char *argv[])
{
lua_State s;
lua_CFunction t = (&Wrapper<decltype(&test)>::template invoke<&test>); // work
t(&s); // no problem
lua_CFunction t2 = register_func(&test);
t2(&s);
return 0;
}
Vollständiger Kompilierungsfehler.
main.cpp: In instantiation of 'int (* register_func(T))(lua_State*) [with T = int (*)(int); lua_CFunction = int (*)(lua_State*)]':
main.cpp:69:40: required from here
main.cpp:58:65: error: no matches converting function 'invoke' to type 'lua_CFunction {aka int (*)(struct lua_State*)}'
lua_CFunction f = (&Wrapper<decltype (fun)>::template invoke<T>);
^
main.cpp:25:7: note: candidate is: template<int (* func)(int)> static int FunctionWrapperImpl<Ret, Args>::ImplementationNonVoid<Indices>::invoke(lua_State*) [with Ret (* func)(Args ...) = func; long unsigned int ...Indices = {0ul}; Ret = int; Args = {int}]
int invoke(lua_State* state) {
Danke für die Erklärung. Eine kleine Frage. Ist es möglich, eine Wrapper-Funktion um den Wrapper zu schreiben, und wenn ja, wie? – a1ien
@ a1ien Nun, eine Lösung könnte sein, zu dem erstellten Wrapper neben dem Funktionstyp direkt einen Zeiger auf die Funktion zu übergeben, die Sie in der 'invoke'-Methode aufrufen möchten, aber es hängt wirklich von Ihren tatsächlichen Bedürfnissen ab ... –
I versuchen Sie diese Vorlage lua_CFunction register_func (Ret (* func) (Args ...)) { \t lua_CFunction f = \t \t \t (& Wrapper :: Vorlage aufrufen ); \t Rückgabe f; } –
a1ien