tags:

views:

187

answers:

6

I am trying to use qsort from STL to sort array of edge:

struct edge
{
    int w,v,weight;
};

by weight. What I am trying is:

int compare_e(const void *a, const void *b)
{
    return ( *(edge *)a->weight - *(edge *)b->weight );
};

But I get:

`const void*' is not a pointer-to-object type

EDIT: Ok thx, now my code is compiled but sort seems don't work 100%...

#include <cstdlib>
#include <iostream>


struct edge
{
    int w,v,weight;
};

struct edge_ID:edge
{
    int id;
};

int compare_e(const void *a, const void *b)
{
    return ( ((edge *)a)->weight > ((edge *)b)->weight );
};

int main()
{   
    using namespace std;

    edge *tab = new edge[100];

    for(int i = 0; i < 100; i++)
    {
        tab[i].weight = rand() % 100;
        cout << i << " => " << tab[i].weight << endl;
    }


    qsort(tab, 100, sizeof(edge), compare_e);

    cout << "AFTER:" << endl;
    for(int i = 0; i < 100; i++)
    {
        cout << i << " => " << tab[i].weight << endl;
    }


    system("PAUSE");
    return EXIT_SUCCESS;
}

I have some number in wrong place...

+3  A: 

You can do it:

int compare_e(const void *a, const void *b)
{
    return  ((edge *)a)->weight - ((edge *)b)->weight ;
}

but if you are writing C++ code, I can't see any reason for doing so - why do you need to use this compare_e function?

anon
Check edit plz:)
MMM
+3  A: 

You need ((const edge *)a)->weight - ((const edge *)b)->weight.

Oli Charlesworth
+2  A: 

You need an extra parenthesis and should not dereference your pointer with *

((edge *)a)->weight

To answer your addition, your compare_e function is now wrong! Keep the first version that substract both weights.

A compare function should return a negative is A < B, 0 if A == B and a positive if A > B. You could implement it using if/else but return A - B works in most case.

Vincent Robert
Ahhh thx, I forget I change it from '-' to '>' :)
MMM
+3  A: 

Don't use qsort, use std::sort: http://www.sgi.com/tech/stl/sort.html

Jon
+2  A: 
struct less_by_weight
{
  bool operator()(const edge& lhs, const edge& rhs) const
  {
    return lhs.weight < rhs.weight;
  }
};

int main()
{   
    const std::size_t size = 100;
    edge *tab = new edge[size];

    for(int i = 0; i < size; ++i)
    {
        tab[i].weight = rand() % size;
        std::cout << i << " => " << tab[i].weight << '\n';
    }

    std::sort( tab, tab+size, less_by_weight() ); 

    std::cout << "AFTER:" << '\n';
    for(int i = 0; i < size; ++i)
    {
        std::cout << i << " => " << tab[i].weight << '\n';
    }

    return EXIT_SUCCESS;
}
sbi
THX it seems to works... but anyway do you have any idea why my code with qsort doesn't work good?
MMM
@MMM: No, and I haven't even looked. Using C++, I haven't used `qsort()` for more than a decade. `std::sort()` is easier to use and faster, too (by design, since the call to the comparator will be inlined), so I see no reason to deal with such code. And you should use `std::vector`, too, instead of doing manual memory management.
sbi
+2  A: 

In answer to your question, it is not possible to cast an object to void*. Pointers can be cast to void*, but not objects. References may also be cast, but not to void*.

qsort is not a part of the C++ Standard Template Library, it is a part of the Standard C Library, which is quite different.

STL is definitely the way to go with idiomatic C++. @sbi's answer shows you how to use std::sort with an array of pointers.

Johnsyweb