2

I have a following code

#include <bits/stdc++.h>                                                                               
using namespace std;

int main () {
  pair<int, int> p[4];
  p[0] = pair<int, int>(5, 2); 
  p[1] = pair<int, int>(40, -2);
  p[2] = pair<int, int>(-3, 2); 
  p[3] = pair<int, int>(4, 45);

  auto print_pairii = [](pair<int, int> pp[]) {
    for (int i = 0; i < 4; i++) {
      cout << pp[i].first << " ";
    }   
    cout << endl;
  };  


  print_pairii(p);

  sort(p, p + 4); 

  print_pairii(p);
  return 0;
}

The first print_pairii shows 5 40 -3 4. After sorting the array of pair, the print_pairii shows -3 4 5 40, meaning that the sorting was done in the basis of the first element of the pair.

Why does this happen instead of the basis of the second element? How does sort work in this sense?

user9414424
  • 448
  • 2
  • 9
  • 2
    How is `operator – curiousguy Jan 19 '20 at 07:16
  • Take care with `#include ` ([why](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h)) and `using namespace std;` ([why](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)). Using them together effectively puts the entire standard library into the global namespace with the rest of your code. The results can be comical. You'll probably laugh once you're done screaming and pulling your hair out from the utter insanity of the program's behaviour. – user4581301 Jan 19 '20 at 07:41

3 Answers3

3

Because when using std::sort without specifying comparator, elements are compared using operator<.

1) Elements are compared using operator<.

And the overloaded operator< for std::pair, compares the 1st element firstly, and then the 2nd element if the 1st elements are equal.

Compares lhs and rhs lexicographically, that is, compares the first elements and only if they are equivalent, compares the second elements.

songyuanyao
  • 147,421
  • 15
  • 261
  • 354
1

Why does this happen instead of the basis of the second element? How does sort work in this sense?

Because by default std::sort will sort std::pair::first then std::pair::second.

If you want to sort via second element you have to provide custom comparison operator. Something like:

  sort(p, p + 4,
       [](const std::pair<int, int> &x, const std::pair<int, int> &y) {
           return x.second < y.second;
       });
artm
  • 16,141
  • 4
  • 27
  • 46
0

It's useful to break this down into its components.

std::pair compares lexicographically, as you've just seen: https://en.cppreference.com/w/cpp/utility/pair. std::sort compares (all types) using operator< by default: https://en.cppreference.com/w/cpp/algorithm/sort. Put these two together, and you sort pairs in increasing order of first then second elements.

ariels
  • 403
  • 2
  • 8