我有一个通用函数,用于将东西推送到名为luaU_push的lua堆栈,它必须专门用于任何想要使用它的类型。例如:
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);
}
事实证明Vector2i
实际上是一个typedef。实际类型为Vector2<int>
。在其他一些地方,我使用Vector2f
s,它们只是Vector2<float>
的typedef。
我希望能为Vector2f
提供luaU_push。我可以为Vector2f创建一个重复的函数,但我更喜欢将它作为通用的,所以我可以在任何类型的Vector2<T>
上使用它,但我无法弄清楚这样做的语法。我认为我可以做这样的事情,但这似乎不起作用:
template <>
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);
}
有没有办法按照我想要的方式工作?
编辑:
跟进问题:我本来打算用这个问题的答案来修复一组函数,包括一些只有返回类型不同的函数,但我不认为给出的答案足够了。例如,我有这个功能(基本上与上面的功能相反)
template <>
inline sf::Vector2i luaU_to<>(lua_State* L, int index)
{
return sf::Vector2i(
luaU_getfield<int>(L, index, "x"),
luaU_getfield<int>(L, index, "y"));
}
我不相信有一种方法可以使用重载来以通用方式完成这项工作,而且我不能使用部分特化。有没有办法让它在这种情况下起作用?
答案 0 :(得分:2)
将此答案作为评论。
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);
}
这应该有效。对于模板化函数,“基本模板”函数的优先级始终高于完全专用函数。
编辑::
您已根据返回类型重载了函数“luaU_to”!这是不允许和可能的(除非你使用一些不可理解/不整洁讨厌的技巧)
你可以做的是,为每个返回数据类型创建一个专用版本,不要让编译器进行参数推导,即在模板调用中明确提到数据类型。
答案 1 :(得分:1)
关于您的后续问题:
如上所述,正如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)
}