C++ 处理函数的部分模板专门化时,Typedef和参数包扩展问题
我为代码的冗长提前道歉C++ 处理函数的部分模板专门化时,Typedef和参数包扩展问题,c++,lua,template-meta-programming,C++,Lua,Template Meta Programming,我为代码的冗长提前道歉 我用TMP编写了一个C++中的小Lua绑定生成器,我遇到了一个函数的部分模板特化的需要,我认为它不能用函数重载来解决。为了清楚起见,我省略了实际的Lua代码 编辑:我理解函数不能部分专用化 下面是我想写的代码: 怪事/问题 类型解析不正确。e、 g registrator和registrator::Func不命名类型。 在函数调用中使用参数包扩展的调用站点上,我得到的参数包没有使用“…”扩展,即使它们看起来与在我的原始代码中使用的参数包相同。 编译器:Clang3.7.0
我用TMP编写了一个C++中的小Lua绑定生成器,我遇到了一个函数的部分模板特化的需要,我认为它不能用函数重载来解决。为了清楚起见,我省略了实际的Lua代码
编辑:我理解函数不能部分专用化 下面是我想写的代码: 怪事/问题 类型解析不正确。e、 g registrator和registrator::Func不命名类型。 在函数调用中使用参数包扩展的调用站点上,我得到的参数包没有使用“…”扩展,即使它们看起来与在我的原始代码中使用的参数包相同。 编译器:Clang3.7.0,GCC4.8.1 LuaExtract扩展上下文: 在我看来,要么编译器只是因为类型而陷入困境,要么更可能的是,我遗漏了一些东西。谢谢你抽出时间 编辑:看起来编译器无法解析这些类型,因为LuaMethodRegistar和LuaCallWrapper相互依赖。我如何打破这种依赖事实证明,这些类型似乎相互依赖,因为忽略调用站点中的::模板会产生看似奇怪的错误消息。这是一个简单的错误编译器错误消息案例 当我将LuaCallWrapper移出LuamethodRegistrator时,我忘记将::template添加到此处的成员模板函数调用中:
return LuaReturn(L, LuaMethodRegistrar<_Result, _Class, _Args...>::MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...));
在这里:
一旦进入了Luamethod内部
不使用::Template的模板成员函数调用被视为
这导致编译器试图评估如下内容:LuaExtractL、nArgs。。。他们自己抱怨模板参数包没有扩展为…,这是有道理的
其他类型错误通过这些更改得到修复。不存在函数的部分模板专门化。只有过载。虽然你可以用一个类来代替,但我很清楚,它能让你明白我要做什么。在我意识到我需要不止一个LuaCallWrapper实现之前,参数包扩展工作得很好;现在没有了。LuaExtractL,nArgs。。。追踪你的论点?如果是3整数呢?它会把第一个论点提取三次吗?有什么我看不见的隐藏状态吗?如果不是,您可能需要添加一些迭代方法。或者传入_Args的每种类型都包含预烘焙索引吗?@VoidStar问得好。我不知道您对Lua了解多少,但它通过一个可以使用负索引访问的堆栈进行通信。我获取N_ARGS中的参数数量,并将该数量的整数传递到LuaExtract中。LuaExtract在-nArrgs处提取指定类型的数据,然后从中减去一个。这使得每个后续调用访问堆栈中的下一个最高元素。看见
////////////////// Forward declared above but defined below LuaMethodRegistrar ///////////////////
template <typename _Result, typename _Class, typename ..._Args>
struct LuaCallWrapper
{
using Registrar = LuaMethodRegistrar<_Result, _Class, _Args...>;
enum { N_ARGS = std::tuple_size<std::tuple<_Args...>>::value };
template<_Result(_Class::*_Func)(_Args...)>
static int Call(lua_State* L)
{
// I can't use Registrar here because it gives me the "does not name a type error"
// Yet, when I use the full type, it finds it.
int nArgs = N_ARGS;
return LuaReturn(L, LuaMethodRegistrar<_Result, _Class, _Args...>::MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...));
}
};
template <typename _Class, typename ..._Args>
struct LuaCallWrapper<void, _Class, _Args...>
{
using Registrar = LuaMethodRegistrar<void, _Class, _Args...>;
enum { N_ARGS = std::tuple_size<std::tuple<_Args...>>::value };
template<void(_Class::*_Func)(_Args...)>
static int Call(lua_State* L)
{
int nArgs = N_ARGS;
LuaMethodRegistrar<void, _Class, _Args...>::MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...);
return 0;
}
};
////////////////////// Back in LuaMethodRegistrar::Register //////////////
// register LuaCallWrapper<_Result, _Class, _Args...>::Call<_Func>
template <typename T>
inline T LuaExtract(lua_State* L, int& argCount);
template <>
inline int LuaExtract<int>(lua_State* L, int& argCount)
{
// get result
return result;
}
return LuaReturn(L, LuaMethodRegistrar<_Result, _Class, _Args...>::MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...));
LuaMethodRegistrar<void, _Class, _Args...>::MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...);
return 0;