Here's a function that interpolates between a given value and a value fetched out of a legacy serialization buffer:
template<typename T>
T interpolate(Buffer& buffer, const T currentValue, const float prop)
{
T bufferValue;
buffer.readT(&buferValue);
return currentValue + (bufferValue-currentValue)*prop;
}
This works great for interpolate<float>
and interpolate<int>
and so on. However if I want to pass a more complex structure such as a vector, I'd rather the currentValue parameter was passed by reference instead of by value. I can use overloading to handle that situation:
// in addition to original function
Vector interpolate(Buffer& buffer, const Vector& currentValue, float prop)
{
Vector bufferValue;
buffer.readT(bufferValue);
return currentValue + (bufferValue-currentValue)*prop;
}
Even if you rip out the lerp into a helper function, it still isn't ideal to repeat the function like this when the only difference from the original is the & parameter, especially if there's more than one type I'd like to pass by reference.
I can use traits to auto-detect when to use a reference:
// 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;
}
However now the compiler can't induce the type of T by default, and the calling code has to explicitly state type:
floatVal = interpolate<float>(buffer, floatVal, 0.5f);
vectorVal = interpolate<Vector>(buffer, vectorVal, 0.5f);
Is there anyway to have compact calling code as well as a single defined function?