1

Given that I have a std::set, how do I find out if one element of the set is before the other. For example, something like this -

bool before(const std::set &s, const int first, const int second) const {
  auto it_first = s.find(first);
  auto it_second = s.find(second);
  return it_first <= it_second;
}

The above code does not work since <= is not defined for the bidirectional iterators, but how would one go about doing something like this?

ssb
  • 7,422
  • 10
  • 36
  • 61

2 Answers2

7

A set orders its elements by operator< (by default). The comparator itself can be retrieved via key_comp or value_comp. So if both elements are in the set, the order is defined by the elements themselves - you don't need the iterators:

return s.key_comp()(first, second);

If one or neither are in the set, then it depends on what you want to do in those cases:

if (s.count(first)) {
    if (s.count(second)) {
        return s.key_comp()(first, second);
    }
    else {
        /* no second */
    }
}
else {
    /* no first, possibly second */
}
Barry
  • 286,269
  • 29
  • 621
  • 977
0

If you would look more generic solution than only for std::set this method would work for any container with forward iterator:

template <class T>
bool before( const T &cont, typename T::const_iterator first, typename T::const_iterator second )
{
    for( auto it = cont.begin(); true; ++it ) {
        if( it == first ) return true;
        if( it == second ) return false;
    }
 }

assuming first and second are valid iterators. Now you can have more optimal specialization for std::set and std::map:

return cont.key_comp()( *first, *second );

and for container with random access iterator:

return first < second;
Slava
  • 43,454
  • 1
  • 47
  • 90
  • this is an O(n) check... Since I am using a std::set, I would like to do it in less than that. Otherwise why not use a std::vector – ssb Aug 12 '15 at 19:15