Интерполируя данное значение и значение из сериализации буфера


Вот функция, которая интерполирует между заданным значением и значением, выбранным из устаревших буфер сериализации:

template<typename T>
T interpolate(Buffer& buffer, const T currentValue, const float prop)
{
    T bufferValue;
    buffer.readT(&buferValue);
    return currentValue + (bufferValue-currentValue)*prop;
}

Это прекрасно работает для интерполировать и интерполировать и так далее. Однако, если я хочу пройти более сложные структуры, такие как вектор, я бы предпочел параметр текущий значение был передан по ссылке а не по значению. Я могу использовать перегрузку, чтобы работать в этой ситуации:

// in addition to original function
Vector interpolate(Buffer& buffer, const Vector& currentValue, float prop)
{
    Vector bufferValue;
    buffer.readT(bufferValue);
    return currentValue + (bufferValue-currentValue)*prop;
}

Даже если вы вырвите lerp в вспомогательную функцию, оно еще не идеально повторять функцию, как это, когда единственным отличием от оригинала является и параметр, особенно если есть больше чем один тип мне бы хотелось пройти по ссылке.

Я могу использовать черты автоматически определяет, когда использовать ссылку:

// to replace original function

template<typename T>
struct RefTrait { typedef const T Ref; }

template<>
struct RefTrait<Vector> { typedef const Vector& Ref; }

template<typename T>
T interpolate(Buffer& buffer, typename RefTrait<T>::Ref currentValue, const float prop)
{
    T bufferValue;
    buffer.readT(&buferValue);
    return currentValue + (bufferValue-currentValue)*prop;
}

Однако теперь компилятор не может побудить типа Т по умолчанию, и вызывающий код должен явно указать тип:

floatVal = interpolate<float>(buffer, floatVal, 0.5f);
vectorVal = interpolate<Vector>(buffer, vectorVal, 0.5f);

Есть в любом случае иметь компактный код, а также одной определенной функции?



346
8
задан 9 февраля 2011 в 03:02 Источник Поделиться
Комментарии
1 ответ

Если я правильно понял ваш вопрос правильно, используя RefTrait политики в ваше второе решение является приемлемым, но вы хотите избежать указания шаблона параметры от клиентского кода, который его использует.

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

template <>
struct RefTrait<Vector> { typedef const Vector &Ref; };

template <typename T>
T interpolateImp(Buffer& buffer, typename RefTrait<T>::Ref currentValue, const float prop)
{
T bufferValue;
buffer.readT(&bufferValue);
return currentValue + (bufferValue-currentValue)*prop;
}

template <typename T>
inline T interpolate(Buffer& buffer, T &currentValue, const float prop)
{
return interpolateImp<T>(buffer, currentValue, prop);
}

Его не избежать перегрузки, но это будет по крайней мере помочь с автоподзаводом тип-дедукция, когда вы пытаетесь использовать его:

floatVal  = interpolate(buffer, floatVal, 0.5f);
vectorVal = interpolate(buffer, vectorVal, 0.5f);

И интерполировать оболочку должны сделать оптимизирован в лишь interpolateImp вызова, когда компилятор встраивает его.

Но я бы порекомендовал взглянуть на то, что Майк первый сказал и узнайте действительно, сколько повлиять на производительность это. Если после этого вы все-таки решили продолжить этот маршрут есть две вещи, чтобы держать в уме.


  • Нюанс с помощью вашего текущего RefTrait. На данный момент, Т bufferValue; в интерполировать создает найдите Т переменную, но не инициализировать его. Это создает проблему при t = вектор как const&. Кроме того, это также означает, что вы не можете изменить этот объект позже, если вам нужно. Один возможный способ исправить это, чтобы добавить значение к вашей политике RefTraits. Вы бы затем использовать параметр typename Т::велоэтапе , чтобы создать любой найдет, что нужно интерполировать.

  • Использование шаблонов в этом вопросе позволит снизить ясность кода, если вы дополнительный dilgent. Синтаксис имеет дело взрывается в вашем лице и может быть трудно получить права, особенно если вы пытаетесь покрыть смешные случаи. Убедитесь, что вес на компромиссы.

Редактировать: подумав об Мои выше код немного больше, я заметил, это может быть немного упрощен, просто сохраняя синтаксис такой же, как ОП. Я обновил мины, чтобы отразить это.

4
ответ дан 10 февраля 2011 в 01:02 Источник Поделиться