Sorting class member (functor?)

Apr 11, 2011 at 9:53am

Hi all,

I'm trying to sort a vector using another vector as the sort key. I think I know what I need to do, but I was wondering if someone could tell me if I'm on the right track.

So, both vectors are members of a class. i.e.,

1
2
3
4
5
class Foo {
  private:
    vector<int> data;
    vector<int> key;
};


I fed this to the <algorithm> sort function:

 
sort (data.begin(), data.end(), MySortFunction);


which didn't work since key is a private member. I then made MySortFunction as a member of class Foo, and that gave me compiling errors. I guess the function in the last argument cannot be a class method?

I looked around the Internet and it sounds like I have to use a functor. Define a class like:

1
2
3
4
5
6
7
8
9
class SortByKey {
  public:
    Foo *foo;
    SortByKey (Foo *x) : foo (x) {}
    
    bool operator () (const lhs, const rhs) {
      return (foo -> GetKey (lhs) > foo -> GetKey (rhs));
    }
};


and then call it like this:

 
sort (data.begin(), data.end(), SortByKey (this));


Does this look correct? One thing I'm wondering is if this means SortByKey is instantiated every time I compare two items? That sounds like a lot of objects being created and destroyed -- so I was wondering if there is another way that I've completely missed...

Thank you!

Ray

Last edited on Apr 12, 2011 at 8:13am
Apr 11, 2011 at 11:36am
You can make MySortFunction a "friend" of class Foo which allows it to access its private members:
1
2
3
4
5
6
7
class Foo
{
    friend bool MySortFunction(const Foo&, const Foo&);
private:
    vector<int> data;
    vector<int> key;
};
Apr 11, 2011 at 1:28pm
In your 'Foo' class you can overload the bool operator<(const Foo &f) const then you can call std::sort(data.begin(), data.end());. So you don't need a compare function and you can access the private members
Apr 12, 2011 at 5:04am

Hi,

Thank you both of you for your suggestions! It looks like either solution will work for me and it seems like the use of a functor was a bit overkill. The pages that described it obviously didn't have the exact same problem that I had. And after I saw that page, I was stuck on functors and have been on that, thinking that was my only solution.

Thank you again; I'll use one of the two suggestions!

Apr 12, 2011 at 5:14am
Btw the way, you can use std::mem_fun to convert a member function to a functor:

std::sort(data.begin(), data.end(), std::mem_fun(&Foo::MySortFunction));
Apr 12, 2011 at 5:52am
Thank you, firedraco! I actually don't understand functors well and have been reading up on it the last few days. I didn't know such a function existed; I'll look into it in case I need to use a functor in the future -- thanks!

Topic archived. No new replies allowed.