【问题标题】:Change comparison operators without large conditional block更改没有大条件块的比较运算符
【发布时间】:2016-01-03 10:47:53
【问题描述】:

我正在测试一个数字是否介于两个值之间。我让用户选择逻辑比较是否应在任一(或两者)限制上包含equal to。 他们通过定义一个 struct 来设置它,其中包含两个边缘值以及要使用的比较运算符:

typedef struct {
    double low; 
    double high;
    bool low_equal; //false if a greater than operator (`>`) should be used, true if a greater-than-or-equal-to (`>=`) operator should be used
    bool high_equal; //Same as low_equal but for a less-than operator
} Edges;

创建了一个Edges 数组(下面称为bins),对于每个输入value,我检查它是否位于bin 边缘内。 但是,为了使用所需的一对比较运算符,我最终得到了这个可怕的条件块:

        if (bins[j].low_equal && bins[j].high_equal)
        {
            if (value >= bins[j].low && value <= bins[j].high)
            {
                break;
            }
        }
        else if (bins[j].low_equal)
        {
            if (value >= bins[j].low && value < bins[j].high)
            {
                data[i] = bins[j].value;
                break;
            }
        }
        else if (bins[j].high_equal)
        {
            if (datum > bins[j].low && datum <= bins[j].high)
            {
                break;
            }
        }
        else
        {
            if (value > bins[j].low && value < bins[j].high)
            {
                break;
            }
        }

有没有更好的方法来做到这一点?我可以以某种方式设置要使用的运算符然后调用它们吗?

【问题讨论】:

  • 您可以使用std::function 和运算符功能等价物,例如std::less、std::less_equal等
  • @jramm 如果该值与数组中的多个元素匹配怎么办?

标签: c++ logical-operators comparison-operators


【解决方案1】:

一个简单的方法可能是:

bool higher = (value > bins[j].low) || (bins[j].low_equal && value == bins[j].low); 
bool lower  = (value < bins[j].high) || (bins[j].high_equal && value == bins[j].high); 

if (higher && lower)
{
    // In range
}

【讨论】:

    【解决方案2】:

    你可以在函数上使用指针

    bool less(double lhs, double rhs) { return lhs < rhs; }
    bool less_or_equal(double lhs, double rhs) { return lhs <= rhs; }
    using comp_double = bool(double, double);
    

    然后

    comp_double *low_comp = bins[j].low_equal ? less_or_equal : less;
    comp_double *high_comp = bins[j].high_equal ? less_or_equal : less;
    
    if (low_comp(bins[j].low, value) && high_comp(value, bins[j].high)) {
       // In range
    }
    

    【讨论】:

    • 不用自己定义less之类的东西,std::less等已经有标准函数了
    • 我明白了,它也是 C++14。
    【解决方案3】:

    这对于三元运算符来说是 IMO 的一个很好的例子

    if ((bins[j].low_equal ? bins[j].low <= value : bins[j].low < value) &&
        (bins[j].high_equal ? value <= bins[j].high : value < bins[j].high)) {
       ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-18
      • 1970-01-01
      • 2018-09-23
      • 1970-01-01
      • 1970-01-01
      • 2010-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多