C++ 带有模板化参数的模板函数专门化
我有一个通用函数,用于将内容推送到lua堆栈,名为luaU_push,它必须专门用于任何想要使用它的类型。例如:C++ 带有模板化参数的模板函数专门化,c++,templates,template-specialization,C++,Templates,Template Specialization,我有一个通用函数,用于将内容推送到lua堆栈,名为luaU_push,它必须专门用于任何想要使用它的类型。例如: template <> inline void luaU_push<>(lua_State* L, const Vector2i& val) { lua_newtable(L); luaU_setfield<int>(L, -1, "x", val.x); luaU_setfield<int>(L, -1
template <>
inline void luaU_push<>(lua_State* L, const Vector2i& val)
{
lua_newtable(L);
luaU_setfield<int>(L, -1, "x", val.x);
luaU_setfield<int>(L, -1, "y", val.y);
}
有没有办法让它按我想要的方式工作
编辑:
后续问题:我本来打算用这个问题的答案来修复一组函数,包括一些只因返回类型不同而不同的函数,但我认为给出的答案不足以解决这个问题。例如,我有这个函数(基本上与上面的函数相反)
模板
内联sf::Vector2i luaU_to(lua_State*L,int index)
{
返回sf::Vector2i(
luaU_getfield(L,索引,“x”),
卢乌·格特菲尔德(L,索引,“y”);
}
我不相信有一种方法可以使用重载以一种通用的方式工作,我也不能使用部分专门化。在这种情况下,有什么办法可以让它起作用吗?把这个答案作为一个注释
template < typename T >
inline void luaU_push(lua_State* L, const sf::Vector2<T>& val)
{
lua_newtable(L);
luaU_setfield<T>(L, -1, "x", val.x);
luaU_setfield<T>(L, -1, "y", val.y);
}
模板
内联void luaU_push(lua_State*L,const sf::Vector2&val)
{
新表(L);
luaU_设定场(L,-1,“x”,val.x);
卢乌设定域(L,-1,“y”,val.y);
}
这应该行得通。对于模板化函数,“基本模板”函数的优先级始终高于完全专用的函数
编辑::
您已经根据返回类型重载了函数“luaU_to”!这是不允许的,也是不可能的(除非你使用了一些不可理解/不整洁的下流伎俩)
您可以做的是,为每个返回数据类型创建一个专门的版本,不要让编译器对其进行参数推断,即在模板调用中显式地提到数据类型。
把这个答案作为一个评论
template < typename T >
inline void luaU_push(lua_State* L, const sf::Vector2<T>& val)
{
lua_newtable(L);
luaU_setfield<T>(L, -1, "x", val.x);
luaU_setfield<T>(L, -1, "y", val.y);
}
模板
内联void luaU_push(lua_State*L,const sf::Vector2&val)
{
新表(L);
luaU_设定场(L,-1,“x”,val.x);
卢乌设定域(L,-1,“y”,val.y);
}
这应该行得通。对于模板化函数,“基本模板”函数的优先级始终高于完全专用的函数
编辑::
您已经根据返回类型重载了函数“luaU_to”!这是不允许的,也是不可能的(除非你使用了一些不可理解/不整洁的下流伎俩)
您可以做的是,为每个返回数据类型创建一个专门的版本,不要让编译器对其进行参数推断,即在模板调用中显式地提到数据类型。
对于您的后续问题: 正如上面ArunMu所指出的,重载函数或仅对返回类型专门化模板是非法的 你可以这样做:
class LuaCheck {
public:
LuaCheck (lua_State* L, int index)
: L_(L), index_ (index)
{ }
operator int () { return luaL_checkinteger(L_, index_); } // (a)
operator double () { return luaL_checknumber(L_, index_); } // (b)
private:
lua_State* L_;
int index_;
};
int main () {
lua_State * L = ...;
int index = ...;
int a = LuaCheck (L, index); // will call (a)
double b = LuaCheck (L, index); // will call (b)
}
对于您的后续问题: 正如上面ArunMu所指出的,重载函数或仅对返回类型专门化模板是非法的 你可以这样做:
class LuaCheck {
public:
LuaCheck (lua_State* L, int index)
: L_(L), index_ (index)
{ }
operator int () { return luaL_checkinteger(L_, index_); } // (a)
operator double () { return luaL_checknumber(L_, index_); } // (b)
private:
lua_State* L_;
int index_;
};
int main () {
lua_State * L = ...;
int index = ...;
int a = LuaCheck (L, index); // will call (a)
double b = LuaCheck (L, index); // will call (b)
}
函数模板不能部分专用化。n、 m.是对的:你应该让你的函数过载。但是你也可以在专业化之前发布你原来的通用的
luaU\u push
函数吗?我无法理解,如果您需要专门化evry类型,为什么需要使用此通用模板函数…@Francesco:。也许我可以不用重载,但我确实喜欢模板专门化带来的对称性。e、 g.lua\u push布尔值
与lua\u push
相同,它清楚地表明要推送到lua的类型是您所期望的类型。函数模板不能部分专用。n、 m.是对的:你应该让你的函数过载。但是你也可以在专业化之前发布你原来的通用的luaU\u push
函数吗?我无法理解,如果您需要专门化evry类型,为什么需要使用此通用模板函数…@Francesco:。也许我可以不用重载,但我确实喜欢模板专门化带来的对称性。e、 g.lua\u push布尔值
与luaU\u push
相同,并且它清楚地表明,您推送到lua的类型是您所期望的类型。在我的原始示例中,将模板专门化为重载是有效的,但在我的另一个示例中则不行(问题中添加了第二个示例)-有什么方法可以让它也起作用吗?@Alex:看到你的代码,一个快速的答案是否定的。函数不能基于返回类型重载(const是一个小的例外),使我的模板专门化成为重载在我的原始示例中起作用,但在我的另一个示例中不起作用(问题中添加的第二个示例)-有没有办法让它也起作用?@Alex:看到你的代码,一个快速的答案是否定的。函数不能根据返回类型重载(const的一个小例外)