Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板函数包装器_C++_Templates_Lua_Function Call - Fatal编程技术网

C++ 模板函数包装器

C++ 模板函数包装器,c++,templates,lua,function-call,C++,Templates,Lua,Function Call,我试图将任何函数包装成只接受一个参数的函数(状态解释器)。如果我直接传递这个函数,一切都很好。 但是如果我在一个附加函数中包装,我会得到一个编译器错误。 请解释一下,我做错了什么 #include <iostream> template <std::size_t... Is> struct _indices { template <template <size_t...> class Receiver> using Relay =

我试图将任何函数包装成只接受一个参数的函数(状态解释器)。如果我直接传递这个函数,一切都很好。 但是如果我在一个附加函数中包装,我会得到一个编译器错误。 请解释一下,我做错了什么

#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;
}
#包括
模板
结构索引{
模板
使用继电器=接收器;
};
模板
结构索引构建器:{u索引构建器{};
模板
结构索引生成器{
使用类型=_指数;
};
结构lua_状态
{};
模板
结构FunctionWrapperImpl{
模板
结构实现非类{
模板静态内联
int调用(lua_状态*状态){
func(10);
返回1;
}
};
使用实现=
typename\u索引\u生成器::类型::模板中继<
实现非类
>;
};
模板
结构包装器{
};
模板
结构包装器:
FunctionWrapperImpl::实现{};
int测试(INTA)
{

std::cout以下两组之间存在显著差异:

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

(&Wrapper::template invoke);

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

谢谢您的解释。一个小问题。是否可以在包装器周围编写包装器函数,如果可以,如何编写?@a1ien好的,一个解决方案可能是从m函数类型直接指向要在
invoke
方法内调用的函数的指针,但这实际上取决于您的实际需要…我尝试使用此模板lua\u CFunction register\u func(Ret(*func)(Args…){lua\u CFunction f=(&Wrapper::template invoke);返回f;}正如我所说,您可以将func指针直接传递到包装器,如:
template struct wrapper{…};
(&Wrapper<decltype (fun)>::template invoke<T>);
(&Wrapper<decltype(&test)>::template invoke<&test>);