2012-02-27 156 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) 
}