views:

137

answers:

5
+1  Q: 

C++ sort method

I want to sort a vector using std::sort, but my sort method is a static method of a class, and I want to call std::sort outside it, but it seems to be trouble doing it this way.

On the class:

static int CompareIt(void *sol1, void *sol2) { ... }

std::sort call:

sort(distanceList.at(q).begin(), 
     distanceList.at(q).end(), 
     &DistanceNodeComparator::CompareIt);

Shouldn't it be possible to do this way?

+4  A: 

std::sort takes a comparator that accepts value of the type held in the collection and returns bool. It should generally implement some notion of <. E.g., assuming your distanceList elements have collections of integers (I assume they don't, but for the sake of the example):

static bool CompareIt(int sol1, int sol2) { ... }

And of course you only need to supply a comparator if there isn't already a < operator that does the right thing for your scenario.

Marcelo Cantos
+1  A: 

It should be a boolean method (sort uses operator <() by default to compare values)

a1ex07
A: 

First, the return type should be bool. Actually the requirement is only that the return type be assignable to bool, which int is. But the fact that you're returning int suggests that you might have written a three-way comparator instead of the strict weak ordering required by std::sort.

Your CompareIt function takes two void* pointers as parameters. Is distanceList.at(q) a vector<void*> (or vector of something convertible to void*)? If not, then the comparator inputs aren't right either. Using void* with algorithms also suggests that you're doing something wrong, because much of the point of generic programming is that you don't need opaque pointers that later get cast back to their original type.

Steve Jessop
+1  A: 

The comparison function you've provided has the signature of the one needed by qsort, which is the sorting function that C provided before C++ came along. sort requires a completely different function.

For example if your declaration of distanceList is std::vector<DistanceNode> your function would look like:

static bool CompareIt(const DistanceNode &sol1, const DistanceNode &sol2)
{
    return sol1.key < sol2.key;
}

Notice that sorting a std::list with the standard sort algorithm isn't efficient, which is why list supplies its own sort member function.

Mark Ransom
A: 

As others have mentioned, it needs a boolean return type. Here's an example which works:

#include "stdafx.h"
#include <vector>
#include <algorithm>

using namespace std;

class MyClass
{
public:
    static bool CompareIt(const void *a1, const void *a2)
    {
        return a1 < a2;
    }
};


int _tmain(int argc, _TCHAR* argv[])
{

    // Create a vector that contains elements of type MyData
    vector<void*> myvector;

    // Add data to the vector
    myvector.push_back((void*)0x00000005);
    myvector.push_back((void*)0x00000001);

    // Sort the vector
    std::sort(myvector.begin(), myvector.end(), MyClass::CompareIt);

    // Display some results
    for( int i = 0; i < myvector.size(); i++ )
    {
        printf("%d = 0x%08X\n", i, myvector[i] );
    }

    return 0;
}

[Edit] Updated the code above to make it a little simpler. I'm not suggesting it's nice code, but without know more about the OPs real implementation, it's difficult to give a better example!

Jon Cage
In your example, what is the point of having the CompareIt function, if it's only there to call < operator? In that case std::sort(myvector.begin(), myvector.end()) shouldn't be enough?In my case, I wan't to have polymorphic behaviour depending on the comparator received.
dmessf
I have to say this is a terrible way to (ab)use the STL. While it's *possible* to have a vector of `void *`, it's rarely a good idea to actually do so.
Greg Hewgill
I just wanted an example which plainly worked as a proof of principle for what the OP asked in his/her question. Of course this is a useless / dangerous example when the OP hasn't posted full details of what they're actually solving.
Jon Cage