455,508 Members | 1,813 Online
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,508 IT Pros & Developers. It's quick & easy.

# Comparison function to sort()

 P: n/a I want to use sort() and supply my own comparison function, like bool lessThan(const S& a, const S& b) { return value(a) < value(b); } and then sort by: sort(a.begin(), a.end(), lessThan); All trivial stuff, but I have several different metrics or value() functions if you will. I could copy and paste 100 times so I get 100 functions like: bool lessThan42(const S& a, const S& b) { return value42(a) < value42(b); } but isn't there an easier way? Can't I make lessThan a template function that takes the metric (value() function) as a template argument or some other smart thing that will save me from all that copying and pasting? /David Oct 21 '05 #1
11 Replies

 P: n/a Hi David Rasmussen wrote: All trivial stuff, but I have several different metrics or value() functions if you will. I could copy and paste 100 times so I get 100 functions like: bool lessThan42(const S& a, const S& b) { return value42(a) < value42(b); } but isn't there an easier way? Can't I make lessThan a template function that takes the metric (value() function) as a template argument or some other smart thing that will save me from all that copying and pasting? Indeed, one possibility is template struct my_less_cmp { Acc acc; my_less_cmp(Acc acc = Acc()) : acc(acc) {} bool operator()(const S& a, const S& b) { return acc(a) < acc(b); } }; [...] std::sort(a.begin(), a.end(), my_less_cmp()); Markus Oct 21 '05 #2

 P: n/a Hi again Markus Moll wrote: bool operator()(const S& a, const S& b) Um... yes, of course... bool operator()(const S& a, const S& b) const Markus Oct 21 '05 #3

 P: n/a Markus Moll wrote: Indeed, one possibility is template struct my_less_cmp { Acc acc; my_less_cmp(Acc acc = Acc()) : acc(acc) {} bool operator()(const S& a, const S& b) { return acc(a) < acc(b); } }; [...] std::sort(a.begin(), a.end(), my_less_cmp()); Okay, but then Acc/some_accessor will have to be a functor as well, right? I mean, I can't just pass a function (pointer) as template argument? /David Oct 21 '05 #4

 P: n/a David Rasmussen wrote: but isn't there an easier way? Can't I make lessThan a template function that takes the metric (value() function) as a template argument or some other smart thing that will save me from all that copying and pasting? In addition to Markus's template solution, maybe a functor object may help as well. Something similar to this: class test { public: enum direction { ASCENDING, DESCENDING }; test( direction d = ASCENDING ) : d_( d ) { } bool operator() ( const int & a, const int & b ) { if ( d_ == DESCENDING ) return a > b; return a < b; } private: direction d_; }; .... sort( iv.begin(), iv.end(), test( test::DESCENDING ) ); Cheers, Andre Oct 21 '05 #5

 P: n/a Markus Moll wrote: Indeed, one possibility is template struct my_less_cmp { Acc acc; my_less_cmp(Acc acc = Acc()) : acc(acc) {} bool operator()(const S& a, const S& b) { return acc(a) < acc(b); } }; [...] std::sort(a.begin(), a.end(), my_less_cmp()); Hmm. I don't understand how this could work. My value functions are all of the form: double value42(const S& s) { return bla bla bla; } double value67(const S& s) { return something else bla bla bla something else; } With your solution, I can't write: std::sort(a.begin(), a.end(), my_less_cmp()); which is kind of what I want to do? /David Oct 21 '05 #6

 P: n/a Hi David Rasmussen wrote: Okay, but then Acc/some_accessor will have to be a functor as well, right? I mean, I can't just pass a function (pointer) as template argument? Yes, you can. (Well, not exactly pass it as a template argument...) int some_func(const S& s) { return s.x; } std::sort(a.begin(), a.end(), my_less_cmp(some_func)); Markus Oct 21 '05 #7

 P: n/a David Rasmussen wrote: Markus Moll wrote: Indeed, one possibility is template struct my_less_cmp { Acc acc; my_less_cmp(Acc acc = Acc()) : acc(acc) {} bool operator()(const S& a, const S& b) { return acc(a) < acc(b); } }; [...] std::sort(a.begin(), a.end(), my_less_cmp()); Hmm. I don't understand how this could work. My value functions are all of the form: double value42(const S& s) { return bla bla bla; } double value67(const S& s) { return something else bla bla bla something else; } With your solution, I can't write: std::sort(a.begin(), a.end(), my_less_cmp()); which is kind of what I want to do? /David You can template on a function pointer, yes. That would go something like: template bool compare_function(const int a, const int b) { return (*fxn)(a) < (*fxn)(b); } If you want to template on the parameter to the function, you'll probably have to say "template ", and be doomed to pass it the parameter type as well. Oct 22 '05 #8

 P: n/a David Rasmussen wrote: Okay, but then Acc/some_accessor will have to be a functor as well, right? I mean, I can't just pass a function (pointer) as template argument? Yes, you can. But a function object is usually faster. Oct 22 '05 #9

 P: n/a Rolf Magnus wrote: David Rasmussen wrote:Okay, but then Acc/some_accessor will have to be a functor as well,right? I mean, I can't just pass a function (pointer) as templateargument? Yes, you can. But a function object is usually faster. How come? /David Oct 22 '05 #10

 P: n/a David Rasmussen wrote: Okay, but then Acc/some_accessor will have to be a functor as well,right? I mean, I can't just pass a function (pointer) as templateargument? Yes, you can. But a function object is usually faster. How come? Because the function is called directly instead of through a pointer. The compilers that I know never inline functions called through a pointer. If the comparison function is very short (and comparison functions tend to be short), inlining can make a big difference. Oct 22 '05 #11

 P: n/a Rolf Magnus wrote: Because the function is called directly instead of through a pointer. The compilers that I know never inline functions called through a pointer. If the comparison function is very short (and comparison functions tend to be short), inlining can make a big difference. I suspected an answer along those lines. Thanks. /David Oct 22 '05 #12

### This discussion thread is closed

Replies have been disabled for this discussion.