带模板化参数的模板函数特化

时间:2012-02-27 07:03:09

标签: c++ templates template-specialization

我有一个通用函数,用于将东西推送到名为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"));
}

我不相信有一种方法可以使用重载来以通用方式完成这项工作,而且我不能使用部分特化。有没有办法让它在这种情况下起作用?

2 个答案:

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