2012-02-27 152 views
0

我有一个通用函数,用于将内容推送到称为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。

我希望能够有一个luaU_push Vector2f s。我可以为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")); 
} 

我不相信有使用过载,使这项工作在一个通用的方式的方式,我可以” t使用部分专业化。有什么办法可以让它在这种情况下工作?

+1

函数模板不能是部分专业。 [改用超载](http://www.gotw.ca/publications/mill17.htm)。 – 2012-02-27 07:15:07

+0

n.m.是对的:你应该重载你的函数。但是,您是否也可以在专业化之前发布您的原始通用'luaU_push'函数?我不明白你为什么需要这个通用模板函数,如果你需要专门为evry类型的话... – Francesco 2012-02-27 07:43:39

+0

@Francesco:[代码在这里](https://bitbucket.org/alexames/luawrapper/src /1a4b8ab1b737/LuaWrapperUtil.hpp)。也许我只能重载,但我确实喜欢模板专业化的对称性。例如'lua_pushboolean'与'luaU_push '相同 - 并且清楚地表明您推送给Lua的类型是您期望的。 – Alex 2012-02-27 07:55:37

回答

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”!这是不允许的,可能(除非你使用一些非无可厚非/邋遢肮脏的伎俩)

你可以做的是,为每个返回的数据类型的专用版本,不要让编译器做即参数推导在模板调用中明确提及数据类型。

+0

使我的模板专业化到一个重载工程的情况下,我的原始示例,但在另一种情况下,我没有(第二个例子已添加到问题) - 有没有办法使这项工作? – Alex 2012-02-27 08:04:57

+0

@Alex:看到你的代码,快速回答将是NO。函数不能在返回类型的基础上重载(在const的情况下是一个小的异常) – Arunmu 2012-02-27 08:18:56

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