2012-10-02 143 views
5

有一個類包含一些數據,並在某個時間點對它們進行排序。我使用qsort(),我想保留類中的比較函數作爲方法。問題是如何將方法傳遞給qsort()以便編譯器(g ++)不會拋出任何警告?如何將方法傳遞給qsort?

嘗試1:

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

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

這種方式產生一個錯誤:

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

嘗試2:

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

這種方式生成一個警告:

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

如何以正確的方式做到這一點呢?

+1

你不應該在C++中使用'qsort'。決不。永遠。 'std :: sort'是*更快*,更靈活和類型安全,'qsort'不是。只要忘記'qsort'曾經存在過,至少除非你到了需要使用普通C的環境。 –

+0

你應該使用'std :: sort'而不是'C'函數'qsort'。這個函數使用'void *'參數這一事實違背了編譯器可以做出的大多數優化(conf H. Sutter)。 – log0

+2

事實上,如果'Data'具有非平凡的拷貝構造函數或非平凡的析構函數,那麼使用'qsort'就是Undefined Behavior。它可以做任何事情,嘔吐整個記憶是更令人愉快的可能性之一。 –

回答

3

您傳遞函數爲&Data::compare_records,但你應該把它作爲Data::compare_records,也使其static

+3

這兩者在C++中是等價的,而且迂迴地說,第一個版本實際上對於意圖更具表現力。 –

+0

謝謝,不知道。其實,函數名已經是一個指向函數的指針,這就是我記憶中的,也許這就是爲什麼我忘了,'&'在那裏不被禁止 –

6

如果必須使用qsort,而不是std::sort推薦),宣佈該成員方法static應該夠了。

+1

我真的會讓「(推薦)」變得更強。 'std :: sort'更快*,更靈活*和*類型安全。 –

+0

和更大(生成更多的二進制代碼)。但是如果你關心這一點,你可能首先不會使用C++。 –

0

此代碼還可以幫助作爲一個提示,爲的std ::排序儘管我使用Qt的快速排序()

風向標可以很酷。

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