0

This is the function I'm trying to simplify:

void BaseCharacter::ClimbLadder(float AxisValue)
{
    if (AxisValue > 0.f)
        ClimbUpLadder<bIsClimbingLaddersFast>();
    else if (AxisValue < 0.f)
        ClimbDownLadder<bIsClimbingLaddersFast>();
}

With bIsClimbingLaddersFast being a Boolean member variable. Now, the code doesn't compile because the value of the Boolean needs to be known in compile time. This is the trivial solution:

void BaseCharacter::ClimbLadder(float AxisValue)
{
    if (bIsClimbingLaddersFast)
    {
        if (AxisValue > 0.f)
            ClimbUpLadder<true>();
        else if (AxisValue < 0.f)
            ClimbDownLadder<true>();
    }
    else
    {
        if (AxisValue > 0.f)
            ClimbUpLadder<false>();
        else if (AxisValue < 0.f)
            ClimbDownLadder<false>();
    }
}

But I'm wondering if there is a cleaner way to write this, one without the duplicate if-else statements. C++14 is being used.

TheBojanovski
  • 137
  • 1
  • 7
  • 2
    Could you pass the boolean into the function as an argument instead of a templated argument? – Lily Nov 20 '20 at 17:33
  • 6
    Personally I would change `ClimbUpLadder` and `ClimbDownLadder` from being a templates to taking a bool parameter. Then you could just have `if (AxisValue > 0.f) ClimbUpLadder(bIsClimbingLaddersFast); else if (AxisValue < 0.f) ClimbDownLadder(bIsClimbingLaddersFast);` – NathanOliver Nov 20 '20 at 17:33
  • 2
    Is it intentional that you have no action for `AxisValue == 0.0f`? – Fred Larson Nov 20 '20 at 17:33
  • Yeah, it's intentional for AxisValue == 0 to have no code. – TheBojanovski Nov 20 '20 at 17:37
  • 1
    Ok, good to know. I thought that could make a difference in answers. – Fred Larson Nov 20 '20 at 17:42
  • Yeah, I can change them so that they only take parameters. But there might be some neat tricks you could do here that I don't know about. – TheBojanovski Nov 20 '20 at 17:46
  • 1
    no matter what trick you apply you need to map from the runtime value to a compile time value somehow. Nathans solution makes the caller more clean, while your solution puts the mapping on the caller, pick your poison. If you never know `bIsClimbingLaddersFast` at compile time, why is it a template parameter in the first place? – 463035818_is_not_an_ai Nov 20 '20 at 18:23
  • Fair point! It's templated because it was used in a slightly different way (observer pattern), but now the code has changed and I was reluctant to remove templates in hopes of c++ providing some simple syntax to move runtime boolean to compile time boolean. At this point I already went with what Nathan said. – TheBojanovski Nov 21 '20 at 00:28

1 Answers1

1

A possible (totally untested code) solution.

template<bool climb>
void BaseCharacter::ClimbLadder(float AxisValue) {
    if (AxisValue > 0.f)
        ClimbUpLadder<climb>();
    else if (AxisValue < 0.f)
        ClimbDownLadder<climb>();
}

void BaseCharacter::ClimbLadder(float AxisValue) {
    if (bIsClimbingLaddersFast)
        ClimbLadder<true>(AxisValue);
    else
        ClimbLadder<false>(AxisValue);
} 
Surt
  • 15,501
  • 3
  • 23
  • 39