Специализация шаблонной функции с шаблонным аргументом - PullRequest
0 голосов
/ 27 февраля 2012

У меня есть универсальная функция для добавления материала в стек 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, "y", val.y);
}

Оказывается, что Vector2i на самом деле является typedef.Настоящий тип - Vector2<int>.В некоторых других местах я использую Vector2f s, которые являются просто typedef для Vector2<float>.

Я бы хотел иметь возможность luaU_push для Vector2f с.Я мог бы создать дублирующую функцию для 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 ]

2 голосов
/ 27 февраля 2012

Примите этот ответ как КОММЕНТАРИЙ.

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

Это должно сработать.А в случае шаблонных функций функция «базового шаблона» всегда будет иметь более высокий приоритет, чем полностью специализированная.

EDIT ::

Вы перегрузили функцию "luaU_to" на основетип возврата!Что недопустимо и невозможно (если вы не используете какой-то непонятный / неопрятный противный прием)

Что вы можете сделать, это создать специализированную версию для каждого возвращаемого типа данных и не позволять компилятору делать вывод аргумента для, т. Е.упомяните тип данных явно в вызове шаблона.

1 голос
/ 27 февраля 2012

По вашему последующему вопросу:

Как уже отмечал 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)
}
...