c++ - 使用 qSort 时遇到问题

标签 c++ qt qt4

我有这个代码:

QVector<LogEvent *> currentItems;
//add a bunch of LogEvent objects to currentItems
qSort(currentItems.begin(), currentItems.end());

这是我的 LogEvent 类:

日志事件.h:

//LogEvent.h
class LogEvent : public QTreeWidgetItem {

public:
    LogEvent();
    LogEvent(QDateTime, LogEvent *parent = 0);
    ~LogEvent();

    bool operator<(const LogEvent *);
    bool operator>(const LogEvent *);
    bool operator<=(const LogEvent *);
    bool operator>=(const LogEvent *);
    bool operator==(const LogEvent *);

private:

    QDateTime timestamp;
};

日志事件.cpp:

//LogEvent.cpp
LogEvent::LogEvent()
{

}

LogEvent::LogEvent(QDateTime timestamp, LogEvent *parent)
    : QTreeWidgetItem(parent)
{
    this->timestamp = timestamp;
}

bool LogEvent::operator<(const LogEvent * event) {
    return (this->timestamp < event->timestamp);
}

bool LogEvent::operator>(const LogEvent * event) {
    return (this->timestamp > event->timestamp);
}

bool LogEvent::operator<=(const LogEvent * event) {
    return (this->timestamp <= event->timestamp);
}

bool LogEvent::operator>=(const LogEvent * event) {
    return (this->timestamp >= event->timestamp);
}

bool LogEvent::operator==(const LogEvent * event) {
    return (this->timestamp == event->timestamp);
}

在我进行排序后,currentItems 中的 LogEvent 对象没有正确排序。我很确定我的运算符重载正在工作。

当我做这样的事情时:

std::cout << currentItems[0]<=currentItems[1]?"T":"F";

它将输出正确的值。

那么我哪里做错了,我该如何改正呢?

最佳答案

qSort 正在对指针进行排序,而不是对这些指针指向的对象进行排序。如果你想用 qSort 对 LogEvents 进行排序,你将不得不按值而不是按引用存储它们(并且还有采用引用的比较运算符,qSort 不会找到你的指针比较函数),或者传递第三个带有您定义的函数的参数。

可能需要用例子来解释为什么会这样。

LogEvent event1, event2;
LogEvent *eventptr1=&event1,*eventptr2=&event2;
event1<event2; // Operator not defined in your code
event1<eventptr2; // This will call the operator you have defined
eventptr1<eventptr2; // This will compare the pointers themselves, not the LogEvents. The pointers are not dereferenced here.

预计到达时间:为了接受一个完整的答案,我将从这里的其他答案中摘取一些好的部分。

首先,定义一个小于操作符的标准语法:

class LogEvent : public QTreeWidgetItem {

public:
  // ...
  bool operator<(const LogEvent *); // Non-standard, possibly reasonable for use in your own code.
  bool operator<(const LogEvent &); // Standard, will be used by most template algorithms.
  // ...
}

日志事件.cpp

bool LogEvent::operator<(const LogEvent &event) {return timestamp<event.timestamp;}

完成此操作后,您可以使用来自 leemes 的答案的此模板取消引用和比较:

template<class T>
bool dereferencedLessThan(T * o1, T * o2) {
    return *o1 < *o2;
}

像这样对你的列表进行排序:

QVector<LogEvent *> currentItems;
//add a bunch of LogEvent objects to currentItems
qSort(list.begin(), list.end(), dereferencedLessThan<LogEvent>);

为了完整起见,最好为所有比较定义标准语法比较运算符。是否保留非标准比较运算符取决于您。

关于c++ - 使用 qSort 时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8186478/

相关文章:

c++ - Sqlite3 ORM for C++ 实现延迟加载

c++ - Qt5 - glTexStorage2D/glBindImageTexture 未定义?

python - 使用 pyqtgraph 高效地绘制大型数据集

c++ - 如何将 CSS 样式类添加到 QWidget

c++ - 当 b 为零时,为什么 a%b 会产生 SIGFPE?

c++ - Qt 样式表和 QML 有什么区别?

qt - 在没有GUI的情况下获取字体指标(控制台模式)

linux - 在 Qt 中保存/打开对话框本地化

c++ - C++ & Qt 应用程序的测试过程

c++11 异步延续或尝试 .then() 语义