模板函数包装器

Template function 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;
}

完整编译错误。

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) {

两者之间存在显着差异:

(&Wrapper<decltype (fun)>::template invoke<T>);

(&Wrapper<decltype(&test)>::template invoke<&test>);

在前者中你使用 T 这显然是你在后者中传递的函数的 类型 你提供 函数指针 到调用方法。由于 invoke 方法接受非类型模板参数,这里是函数指针,第二个代码编译正确。请记住 - 您不能将非类型模板参数与类型模板参数混合使用,就像您不能将类型模板参数与模板模板参数混合使用一样。