tags:

views:

198

answers:

2

I'm having a problem sorting my derived classes with the STL sort function.

Example -

The header:

vector<AbstractBaseClass *> *myVector;

In the ImpL:

sort(myVector->begin(), myVector->end(), compareBy);

The comparator:

bool MyClass::compareBy(AbstractBaseClass& a, AbstractBaseClass& b) {
    return (a->someMethod() < b->someMethod());
}

Edit: This question is geared toward general usage of sorting abstract classes with the STL (I'm not posting a trace dump). If its not apparent already, I'll say that there is no way in hell it can compile as printed. Rather, I'm asking (given the data structures) how one would typically sort with this toy abstract class.

Thanks for the quick answers, I believe you guys already nail'd it!

Got'a love StackOverFlow!

+6  A: 

An example:

struct Abstr { virtual int some()const == 0; };

bool abstrSmaller( const Abstr* a1, const Abstr* a2 ) { 
   return a1->some() < a2->some(); 
}

int main() {
   vector<Abstr*> v;

   sort( v.begin(), v.end(), abstrSmaller );
}
  1. The compare function should not be a member function: either a static or a free function.
  2. It should take the vector's elements as argument, i.e. a pointer, not a reference.
  3. It can call const functions, so it can accept const arguments.
xtofl
Perfect, thanks xtofl for the quick response!
Rev316
+4  A: 
  1. That compareBy must not be a non-static member function (since this would require the implicit this pointer to be passed to the function by the compiler). You can either make it a static member, a free function, or a function object. The latter is generally better, as it usually allows better optimization (although in your code the abstraction penalty might undo that anyway).
  2. The comparison must take your vector's value_type, and that's an AbstractBaseClass*, not an AbstractBaseClass&.

This would look like the following:

struct compareBy : public std::binary_function< const AbstractBaseClass*
                                              , const AbstractBaseClass*
                                              , bool > {
  bool operator()(const AbstractBaseClass* a, const AbstractBaseClass* b) {
    return (a->someMethod() < b->someMethod());
  }
};

You can also make this comparator a private member of your class, so it doesn't pollute any namespace.

sbi
For completeness, you'd want to inherit it from `binary_function`.
GMan
@GMan: Good idea! Done.
sbi