Можно ли привести объект класса к void *? - PullRequest
3 голосов
/ 26 мая 2010

Я пытаюсь использовать qsort из STL для сортировки массива ребер:

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

по весу. Что я пытаюсь это:

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

Но я получаю:

`const void * 'не является тип указателя на объект

EDIT: Хорошо, спасибо, теперь мой код скомпилирован, но сортировка, кажется, не работает на 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;
}

У меня есть номер в неправильном месте ...

Ответы [ 6 ]

3 голосов
/ 26 мая 2010

Не используйте qsort, используйте std :: sort: http://www.sgi.com/tech/stl/sort.html

3 голосов
/ 26 мая 2010

Вам нужно ((const edge *)a)->weight - ((const edge *)b)->weight.

3 голосов
/ 26 мая 2010

Вы можете сделать это:

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

но если вы пишете код на C ++, я не вижу никакой причины для этого - зачем вам использовать эту функцию compare_e?

2 голосов
/ 26 мая 2010

Отвечая на ваш вопрос, невозможно привести объект к void*. Указатели можно привести к void*, но не к объектам. Ссылки также могут быть разыграны, но не на void*.

qsort не является частью стандартной библиотеки шаблонов C ++, она является частью стандартной C библиотеки, которая совершенно иная.

STL определенно подходит для идиоматического C ++. Ответ @ sbi показывает, как использовать std::sort с массивом указателей.

2 голосов
/ 26 мая 2010
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;
}
2 голосов
/ 26 мая 2010

Вам нужны дополнительные скобки, и вы не должны разыменовывать указатель с помощью *

((edge *)a)->weight

Чтобы ответить на ваше добавление, ваша compare_e функция теперь неверна! Оставьте первую версию, которая вычитает оба веса.

Функция сравнения должна возвращать отрицательное значение A < B, 0, если A == B, и положительное значение, если A > B. Вы можете реализовать это, используя if/else, но в большинстве случаев return A - B работает.

...