【问题标题】:C++: Is there any way to have conditional operators based on a value in order to simplify blocks of code?C++:有没有办法让条件运算符基于一个值来简化代码块?
【发布时间】:2015-09-28 16:59:03
【问题描述】:

比如说:

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 语句中使用

【问题讨论】:

  • 如果CubicInterpDerivative == 0怎么办?
  • 没关系,什么都不会发生,值需要在导数从正到负或负到正的符号变化后改变,具体取决于阶段。
  • 这些都是很好的答案,解决了我不知道/不知道的不同事情,谢谢。

标签: c++ conditional simplify


【解决方案1】:

这部分应该放在一个变量中。

(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;
}

【讨论】:

  • 是的,谢谢你提醒我这样做,尽管我对带有运算符的条件语句感到好奇,如果我的用例被扩展为具有多个不同的情况,这将形成一个非常大的条件语句。
【解决方案2】:

一般来说,如果你想要一个可切换的操作符,像这样:

#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;
    }
}

【讨论】:

  • 有趣,不知道你可以做这样的事情,谢谢。
  • 编译器能否像使用原生运算符一样优化这一点?
  • @ChrisBetti ,不,因为您正在根据运行时值切换运算符。优化的解决方案类似于发布的 ergonaut - 简化整体代码。但是,当人们真正想要在没有代码重复的情况下进行运行时选择时,就可以做到。
【解决方案3】:

将比较逻辑拉到一个通用函数或类中

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;
}

【讨论】:

    【解决方案4】:

    我会从一些现有的答案中采用这种方法:

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 2019-04-03
      • 1970-01-01
      • 2017-03-08
      • 2020-11-30
      • 2015-01-13
      • 1970-01-01
      • 2020-07-07
      • 1970-01-01
      • 2023-01-07
      相关资源
      最近更新 更多