C ++: есть ли способ иметь условные операторы, основанные на значении, чтобы упростить блоки кода?

Скажем, например:

if(CurrentRotationStage % 2 == 0)
{
if(FMath::CubicInterpDerivative(CubicPoint[CurrentRotationStage], 0.f, CubicPoint[(CurrentRotationStage + 1) % 4], 0.f, MainMenuWidget->TrumpAngle / RotationLimit) < 0.f)
{
CurrentRotationStage = ++CurrentRotationStage % 4;
MainMenuWidget->TrumpAngle -= RotationLimit;
}
}
else
{
if(FMath::CubicInterpDerivative(CubicPoint[CurrentRotationStage], 0.f, CubicPoint[(CurrentRotationStage + 1) % 4], 0.f, MainMenuWidget->TrumpAngle / RotationLimit) > 0.f)
{
CurrentRotationStage = ++CurrentRotationStage % 4;
MainMenuWidget->TrumpAngle -= RotationLimit;
}
}

В принципе, если CurrentRotationStage является четным, я хочу использовать < в моем утверждении if, и наоборот, если это странно. Есть ли способ упростить это, чтобы предотвратить использование нескольких if / elses?

1

Решение

В общем, если вы хотите переключаемый оператор, примерно так:

#include <iostream>
#include <algorithm>
#include <functional>

int main() {
std::function<bool(int,int)> op = std::less<int>();
std::cout << "Defaulting to less-than" << std::endl;

int x = 5;
if (x & 1) {
op = std::greater<int>();
std::cout << "Chosing greater-than because number is odd" << std::endl;
}

if (op(x, 4)) {
std::cout << x << " is op(4)" << std::endl;
}
}
2

Другие решения

Эта часть должна быть помещена в переменную.

(FMath::CubicInterpDerivative(CubicPoint[CurrentRotationStage], 0.f, CubicPoint[(CurrentRotationStage + 1) % 4], 0.f, MainMenuWidget->TrumpAngle / RotationLimit)

Тогда это будет выглядеть так:

blah = calculateIt...
if(CurrentRotationStage % 2 == 0 && blah < 0.f) ||
(CurrentRotationStage % 2 != 0 && blah > 0.f){
CurrentRotationStage = ++CurrentRotationStage % 4;
MainMenuWidget->TrumpAngle -= RotationLimit;
}
4

Потяните логику сравнения в общую функцию или класс

class RotationChecker
{
public:
explicit RotationChecker(int stage): stage_(stage) {}
bool operator()(float f) const { return stage % 2 == 0 ? f < 0.f : f > 0.f; }
private:
int stage_;
};

RotationChecker checker(CurrentRotationStage);
float value = FMath::CubicInterpDerivative(CubicPoint[CurrentRotationStage], 0.f,
CubicPoint[(CurrentRotationStage + 1) % 4], 0.f,
MainMenuWidget->TrumpAngle / RotationLimit);
if (checker(value)))  // or "if (RotationChecker(CurrentRotationStage)(value))"{
CurrentRotationStage = ++CurrentRotationStage % 4;
MainMenuWidget->TrumpAngle -= RotationLimit;
}
0

Я бы взял подход из нескольких существующих ответов:

std::function<bool (int, int)> fn = std::less<int>();
if (CurrentRotationStage % 2 == 0)
{
fn = std::greater<int>();
}

float result = FMath::CubicInterpDerivative(CubicPoint[CurrentRotationStage], 0.f, CubicPoint[(CurrentRotationStage + 1) % 4], 0.f, MainMenuWidget->TrumpAngle / RotationLimit);

if (fn(result, 0.f))
{
CurrentRotationStage = ++CurrentRotationStage % 4;
MainMenuWidget->TrumpAngle -= RotationLimit;
}
0
По вопросам рекламы [email protected]