Problems with std::sort()

I use comparator with the function sort(), but when I run it, an error "invalid operator<". The input data is:

8

1 9
1 1100
24 100
24 11101
24 4343
23 24
9 4234
9 10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct myclass {
	bool operator() (pair<int,int> i,pair<int,int> j) {
		if(i.first<j.first)
		return true;
	else if(i.first>i.first)
		return false;
	return (i.second<j.second)?true:false;}
} comp;

int main(){
	FILE *fin=fopen("input.txt","r"), *fout=fopen("output.txt","w");
	int n;
	fscanf(fin,"%d\n",&n);
	vector<pair<int,int> > b(n);
	int i;
	for(i=0;i<n;i++)
		fscanf(fin,"%d %d\n",&b[i].first,&b[i].second);
	sort(b.begin(),b.end(),comp);
	return 0;
}
Last edited on
try:

 
return(i.first < j.first);


and get rid of all the if else stuff.

is your sort to get each pair in ascending order?

edit 2: i would also make both input parameters const references and the operator method const as well.
Last edited on
std::pair<> is LessthanComparable.
http://en.cppreference.com/w/cpp/utility/pair/operator_cmp
Only if you want something different from normal lexicographic comparison do you need to write your own predicate.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <utility>
#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
   std::vector< std::pair<int,int> > seq { {1,2}, {3,4}, {1,1}, {3,5}, {3,2} } ;

   std::sort( std::begin(seq), std::end(seq) ) ;

   for( auto pair : seq)
        std::cout << '{' << pair.first << ',' << pair.second << "} " ;
   std::cout << '\n' ;
}

http://coliru.stacked-crooked.com/a/f611389964b737e8


> try: return(i.first < j.first);

That, almost certainly, is not what HEDO4EJIOBEK intended. With that predicate, if we put try to insert the five pairs in the snippet into a std::map<>, the last three would be rejected as duplicates.


If a predicate must be written, ideally make it const-correct.

1
2
3
4
5
6
7
8
9
struct my_cmp
{
    // const
    bool operator() ( std::pair<int,int> a, std::pair<int,int> b ) const
    {
        if( a.first == b.first ) return a.second < b.second ;
        else return a.first < b.first ;
    }
};



> i would also make both input parameters const references

IMHO, there is a case for preferring pass by value and return by value over pass by reference and return by reference. Even if the predicate was not inlineable (it is) , all that we would save is the cost of copying two integers.

As C++ programmers, we tend to violate referential transparency all the time; though unlike Java, the language itself does not demand that we must do so.

An amusing thread which surfaced in the Lounge a few weeks back:
http://www.cplusplus.com/forum/lounge/112932/
Innocent code? Not in my book; code that passed Position (a tiny object; a mere pair of integers) by value would have been innocent.
Topic archived. No new replies allowed.