STL函数来测试某个值是否在某个范围内?

时间:2012-02-13 05:12:37

标签: c++ stl

我有一个功能:bool inBounds(int value, int low, int high)。是否有一个STL等价物可以做有用的事情(特别是采用不同类型的变量)?我找不到使用谷歌的人,我更愿意重复使用而不是重写。

4 个答案:

答案 0 :(得分:11)

在C ++ 14中,没有像这样的函数的直接等价物,但对于具有快速相等比较的较小类型,您可以使用std::clamp

if (val == std::clamp(val, low, high)) {
    ...
}

或者,您可以编写自己的函数来测试:

template <typename T>
    bool IsInBounds(const T& value, const T& low, const T& high) {
    return !(value < low) && (value < high);
}

检查value是否在[低,高]范围内。如果你想要范围[低,高],你可以把它写成

template <typename T>
    bool IsInBounds(const T& value, const T& low, const T& high) {
    return !(value < low) && !(high < value);
}

请注意这是如何完全根据operator <定义的,这意味着可以在此处使用任何仅支持operator <的类。

同样,这里有一个使用自定义比较器:

template <typename T, typename R, typename Comparator>
    bool IsInBounds(const T& value, const R& low, const R& high, Comparator comp) {
    return !comp(value, low) && comp(value, high);
}

后者具有很好的优势,lowhigh不必与value类型相同,只要比较器可以处理它就可以工作很好。

希望这有帮助!

答案 1 :(得分:5)

bool inBounds(int value, int low, int high)

有一个小缺点,你必须记住哪个参数在哪里。
在一段时间后返回代码时,我不可能是唯一一个完全理性的参数排序令人困惑的人。

你可以加倍努力并定义

template<typename T>
class Interval
{
public:
    Interval(T lo, T hi) : low(lo), high(hi) {}
    bool contains(T value) const { return low <= value && value < high; }
private:
    T low;
    T high;
};
template<typename T>
Interval<T> interval(T lo, T hi) { return Interval<T>(lo, hi); }

然后你可以更明确地表达你的意思:

if (interval(a, b).contains(value))
    // ...

如果一个人处于抽象模式,那么要概括以适应不同的包容性/排他性组合并不太难。

当然,这对你的目的来说可能有点过分了  YMMV,以及所有这些。

答案 2 :(得分:1)

您可以从std::lessstd::morestd::bindstd::compose撰写一个,但这确实有点过分。

Lambda更容易:

[](int value, int low, int high){return !(value < low) && (value < high);}

或者,如果低和高在范围内

[low, high](int value){return !(value < low) && (value < high)};

答案 3 :(得分:-1)

我几乎认为你最好不要用一个完整的功能尝试这样一个看似微不足道的任务,只是内联行为。

这样的事情:

  1 #include <iostream>
  2 
  3 int main() {
  4     int value = 5;
  5     bool inside = false;
  6     int lower = 0;
  7     int upper = 10;
  8     inside = lower < value && value < upper;
  9     printf("inside: %d", inside);
 10     return 0;
 11 }

如果您有理由不像这样写代码,请告诉我,我可以提供更复杂的答案。