-1

Why *(it) in set upperbound returns index , while *(++it) in set upperbound returns value for the value greater than any value present in the set?

#include<bits/stdc++.h>
using namespace std;
int main() {
 set<int> s;
 s.insert(30);
 s.insert(25);
 int x=35;
 auto it = s.upper_bound(x);
 cout << *(it) << endl; //output: 2
 cout << *(++it) << endl;// output: 25
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Nitin Kumavat
  • 28
  • 1
  • 6
  • 2
    In your code example, there is no element greater than `35` in the set, therefore `it` will point to `s.end()`. Dereferencing or incrementing it is not allowed and causes undefined behavior in both cases. You could be getting any non-sense answer. – walnut Aug 31 '19 at 07:33
  • @uneven_mark the output is same as i mentioned in code comment – Nitin Kumavat Aug 31 '19 at 08:25
  • @NitinKumavat In C++, even if your code appears to work, it's not necessarily valid. If you enable safe iterators, you'll [get an error](http://coliru.stacked-crooked.com/a/4a8e2b81fe4661c7). – HolyBlackCat Aug 31 '19 at 08:39

1 Answers1

2

*(it) does not return an index. If it is an iterator that references a member of the set, then *(it) is equivalent to *it (the () are not required). It therefore accesses the corresponding member of the set. If it is a past-the-end iterator, the behaviour is undefined.

*(++it) first increments it, and then accesses the corresponding set element. So

cout << *(++it) << endl;

gives the same output as

++it;
cout << *it << endl;

which gives undefined behaviour if it was already a past-the-end iterator OR if incrementing it gives a past-the-end iterator.

In your example, the s.upper_bound(x) returns a past-the-end iterator, since x is greater than any member of the set. Both output statements in your code therefore give undefined behaviour.

Peter
  • 35,646
  • 4
  • 32
  • 74