Skip to main content
changed title, added tag
Source Link
Malachi
  • 29.1k
  • 11
  • 87
  • 188

how to eliminate extra overloaded function? Interpolating given value and legacy value from serialization buffer

Here's a function that interpolates between a given value and a value fetched out of a legacy serialisationserialization 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?

how to eliminate extra overloaded function?

Here's a function that interpolates between a given value and a value fetched out of a legacy serialisation 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?

Interpolating given value and legacy value from serialization buffer

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?

Tweeted twitter.com/#!/StackCodeReview/status/36437513358934016
Source Link
tenpn
  • 387
  • 1
  • 9

how to eliminate extra overloaded function?

Here's a function that interpolates between a given value and a value fetched out of a legacy serialisation 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?