equal_range

The expected behavior, does not make sense to me…

If we search for value 4, then the result is an empty sub-range because there is no such element in the input range. In this case, the first iterator returned points to 5 because this is the first element not less than 4; the second iterator points also to the element 5 because this is the first element greater than 4. - Understanding equal_range / cppreference.com

auto [first, last] = std::equal_range(std::cbegin(v), std::cend(v), 4);

caption

What I would expect is more something in the line of this:

if you want the closest entry, you need to check both the returned entry and the one before and compare the differences.

which should translate more or less to this: for [10,13,17]

  • when asking for 13, ok got [13,13[
  • when asking for 14, then got [13,17[
  • when asking for 18, then got [17,end[
  • when asking for 9, then got [10,10[ - which is less than ideal, but work in my specific case
template<class T>
auto bound( int pos, map<int,T>& m) {

  auto lb = m.lower_bound( pos );
  std::pair<typename map<int,T>::iterator, typename map<int,T>::iterator> res;
  res.first = lb;
  res.second = lb;

  if( lb == m.end() && m.size() > 0) {
    // not found, we want to have the last element
    res.first = std::prev( m.end());
  } else if (lb == m.begin()) {
    // or first element
  } else {
    if (lb->first == pos)
      // value found in map
      ;
    else {
      // value not found in map, we want it to be bounded by existing value
        res.first = std::prev(lb);
    }
  }

  return res;
}
Written on January 18, 2022, Last update on January 18, 2022
c++ search