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