2012-10-02 18 views
5

Hay una clase que contiene algunos datos y los ordena en algún momento. Yo uso qsort() y me gustaría mantener la función de comparación dentro de la clase como método. La pregunta es cómo pasar un método al qsort() para que el compilador (g ++) no arroje ninguna advertencia.¿Cómo pasar un método a qsort?

Intento 1:

int Data::compare_records(void * rec_1, void * rec_2){ 
    // [...] 
} 

void Data::sort(){ 
    qsort(records, count, sizeof(*records), &Data::compare_records); 
} 

esta manera genera un error:

error: cannot convert ‘int (Data::*)(const void*, const void*)’ to ‘int (*)(const void*, const void*)’ for argument ‘4’ to ‘void qsort(void*, size_t, size_t, int (*)(const void*, const void*))’ 

Intento 2:

void Data::sort(){ 
    qsort(
    records, count, sizeof(*records), 
    (int (*)(const void*, const void*)) &Data::compare_records 
); 
} 

esta manera genera una advertencia:

warning: converting from ‘int (Data::*)(const void*, const void*)’ to ‘int (*)(const void*, const void*)’ 

¿Cómo hacerlo de la manera correcta, entonces?

+1

No debe utilizar 'qsort' en C++. Nunca. Nunca. 'std :: sort' es * faster *, más flexible y seguro,' qsort' no es nada de eso. Olvidémonos de que 'qsort' existió alguna vez, al menos a menos que alguna vez llegue al entorno en el que necesite utilizar C. simple –

+0

Debería usar' std :: sort' en lugar de la función 'C'' qsort'. El hecho de que esta función tome argumentos 'void *' derrota la mayor parte de la optimización que un compilador podría hacer (conf. H. Sutter). – log0

+2

De hecho, si 'Data' tiene un constructor de copia no trivial o un destructor no trivial, el uso de' qsort' es Undefined Behavior. Puede hacer cualquier cosa, vomitar por toda la memoria es una de las posibilidades más agradables. –

Respuesta

3

que pase la función que &Data::compare_records, pero debe pasarlo como Data::compare_records y también hacen que sea static

+3

Los dos son equivalentes en C++, y pedantemente, la primera versión es realmente más expresiva para la intención. –

+0

Gracias, no sabía de eso. En realidad, el nombre de la función ya es un puntero a una función, eso es lo que recordé y tal vez es por eso que lo olvidé, que '&' no está prohibido allí –

6

Si tiene que usar qsort y no std::sort (recomienda), declarando el método como miembro de static debería ser suficiente.

+1

Realmente haría que el "(recomendado)" sea más fuerte. 'std :: sort' es * más rápido *, más flexible * y * seguro. –

+0

Y más grande (genera más código binario). Pero si te importa eso, probablemente no estés usando C++ en primer lugar. –

0

Este código también puede ayudar como una sugerencia, por std :: sort pesar de I Use qsort de Qt()

Los funtores pueden ser muy geniales.

struct randomWSort 
{ 
    SatoshiGame* This; 
    randomWSort(SatoshiGame* g){This=g;} 
    bool operator()(QString& a, QString& b) 
    { 
     return This->randomWSort(a,b); 
    } 
}; 

bool SatoshiGame::randomWSort(QString& a, QString& b) 
{ 
    return rand->rnd() %2; 
} 

QString SatoshiGame::getRandomString(QStringList words) 
{ 
    qSort(words.begin(), words.end(), ::randomWSort(this)); 
    return words.at(0); 
} 
Cuestiones relacionadas