2012-10-02 14 views
5

Esiste una classe che contiene alcuni dati e li ordina in un determinato momento. Io uso qsort() e mi piacerebbe mantenere la funzione di confronto all'interno della classe come metodo. La domanda è come passare un metodo a qsort() in modo che il compilatore (g ++) non lanci alcun avvertimento?Come passare un metodo a qsort?

Tentativo 1:

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

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

In questo modo genera un errore:

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*))’ 

Tentativo 2:

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

questo modo genera un avvertimento:

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

Come fare nel modo giusto allora?

+1

Non si dovrebbe usare 'qsort' in C++. Mai. Mai. 'std :: sort' è * più veloce *, più flessibile e typesafe,' qsort' non è niente di tutto ciò. Basta dimenticare che 'qsort' è mai esistito, almeno a meno che non si arrivi all'ambiente in cui è necessario utilizzare semplicemente C. –

+0

Si dovrebbe usare' std :: sort' invece della funzione 'C'' qsort'. Il fatto che questa funzione tenga gli argomenti 'void *' sconfigge la maggior parte dell'ottimizzazione che un compilatore potrebbe fare (conf H. Sutter). – log0

+2

Infatti, se 'Data' ha un costruttore di copie non banale o un distruttore non banale, l'uso di' qsort' è Comportamento indefinito. Può fare qualsiasi cosa, vomitando tutta la memoria essendo una delle possibilità più piacevoli. –

risposta

3

Si passa la funzione di &Data::compare_records, ma si dovrebbe passare come Data::compare_records e rendono anche static

+3

I due sono equivalenti in C++, e pedanticamente, la prima versione è in realtà più espressiva all'intenzione. –

+0

Grazie, non lo sapevo. In realtà, il nome della funzione è già un puntatore a una funzione, è quello che ho ricordato e forse è per questo che ho dimenticato, che '&' non è proibito lì –

6

Se è necessario utilizzare qsort e non std::sort (raccomandato), dichiarando il metodo membro come static dovrebbe essere sufficiente.

+1

Vorrei davvero rendere "(consigliato)" più forte. 'std :: sort' è * più veloce *, più flessibile * e * typesafe. –

+0

E più grande (genera più codice binario). Ma se ti interessa, probabilmente non stai usando C++ in primo luogo. –

0

Questo codice può anche aiutare come un suggerimento, per std :: sort nonostante il fatto che l'utilizzo di Qt qsort()

I funzionamenti possono essere molto freschi.

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); 
} 
Problemi correlati