16

I have trouble using the std::sort function with my custom comparison function when defined inside a class.

class Test {
    private:
        vector< vector<int> > mat;
        bool compare(vector<int>, vector<int>);
    public:
        void sortMatrix();
}

bool Test::compare( vector<int> a, vector<int> b) {
    return (a.back() < b.back());
}

void Test::sortMatrix() {
    sort(vec.begin(), vec.end(), compare);
}

I get the following error message:

error: reference to non-static member function must be called
        sort(vec.begin(), vec.end(), compare);
                                     ^~~~~~~

When I however define compare() and sortMatrix() in the file main.cpp without any class, everything works fine. I would appreciate any help and suggestions.

Praveen Vinny
  • 2,372
  • 6
  • 32
  • 40
Lennart
  • 161
  • 1
  • 1
  • 3
  • You cannot use a member function there, change it to `Test` class call operator, and pass `Test` to `sort()` instead: `sort(vec.begin(), vec.end(), Test);` – πάντα ῥεῖ Jun 11 '16 at 19:45

8 Answers8

29
Make your comparator function static. It will work.
arpit1714
  • 543
  • 6
  • 8
7

To call compare you need a Field object. You could use a lambda a call it from in there if you have C++11 support:

sort(vec.begin(), vec.end(), [this] (vector<int> a, vector<int> b) {
    return compare(a, b); });

Or just move your comparison method out of the class, you don't need to access it's members anyway.

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
  • Thank you, I'll try this out. The compare is actually suppose to be a function of Test, I made a typo. bool Test::compare( .. – Lennart Jun 11 '16 at 19:52
6

There are three ways of doing this :

  1. Create a structure with operator() defined for the structure

    struct compareFunc {

     inline bool operator() (const vector<int> &a, const vector<int> &b)
     {
         return (a.back() < b.back());
     }
    

    };

    and in sort function call in the below fashion:

    std::sort(vect.begin(), vect.end(), compareFunc());

  2. If you are using C++11 version then write your lamda function and call the comparator function defined in your class:

     std::sort(vec.begin(), vec.end(), [this](vector<int> a, vector<int> b){
                 return (compareFun(a,b));
    

    });

    Define compareFun in your class in the below mentioned manner:

    class Test { public: bool compareFun(vector a, vector b) { return (a.back() < b.back()); } };

  3. Using static method as mentioned by one of our friend. I hope this works.

Dixit
  • 71
  • 1
  • 5
2
class Test {
    private:
        vector< vector<int> > mat;
        bool compare(vector<int>, vector<int>);
    public:
        void sortMatrix();
}

static bool Field::compare( vector<int> a, vector<int> b) {
    return (a.back() < b.back());
}

void Test::sortMatrix() {
    sort(vec.begin(), vec.end(), compare);
}

The error clearly shows that you are trying to access a non-static member. So, just convert it to static.

1

you can solve this problem by adding "static" keyword before your comparator sort function.

class Solution {
public:
    
     static bool sortby_sec(const pair<int,int>&a,const pair<int,int>&b)
            {
                return (a.second<b.second); 
             }
       
    int maximumUnits(vector<vector<int>>& b, int tr) {
        vector<pair<int,int>>vp;
        for(int i=0;i<b.size();++i)
        {
            vp.push_back(make_pair(b[i][0],b[i][1]));
        }
        sort(vp.begin(),vp.end(),sortby_sec);
        
        int ms=0;
        for(int i=vp.size()-1;i>=0;i--)
        {
             if(tr>vp[i].first)
             {
                 tr-=vp[i].first;
                 ms=ms+vp[i].first*vp[i].second;
             }
              else{
                 ms=ms+tr*vp[i].second;
                  break;

              }
          }
        
       return ms; 
    }
};
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
1

make the "compare" function as static, because sort() function takes static function pointer as an argument.

static bool compare(vector<int>, vector<int>);
0

You are facing this issue because you are trying to access the non-static access member in the function just try to change your comparator. You can use the below code for refernce.

class Test{
    public:
        static bool comp(const vector<int> &a, const vector<int> &b){
        return a[1] < b[1];
    }
    int Intervals(vector<vector<int>>& nums) {
        sort(nums.begin(), nums.end(), comp);
        int count = 0,j=0;
        for(int i = 1; i < nums.size(); i++){
            if(nums[j][1] > nums[i][0])
                count++, j=i; 
            }

       return count;
        }
    };
Ayush Dixit
  • 467
  • 4
  • 10
0

you can use static before the comparator function.

Because

  1. sort function only takes a static function as an argument
  2. Because non-static member functions have an implicit 1st parameter for this. This is how they access other members.

If you want to call the comp function outside of class then you write code like this

a.comp(b,c)

So this is considered as 3 parameters, not as 2.

Sort code is outside your class and you must use the syntax above.

Making the member static allows this call:

Test::comp(b,c)

which is only 2 parameters and matches the predicate std::sort expects.

Sammed
  • 66
  • 7