2012-10-02 52 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); 
}