我有这个代码:
QVector<LogEvent *> currentItems;
//add a bunch of LogEvent objects to currentItems
qSort(currentItems.begin(), currentItems.end());
Run Code Online (Sandbox Code Playgroud)
这是我的LogEvent类:
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;
};
Run Code Online (Sandbox Code Playgroud)
LogEvent.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);
}
Run Code Online (Sandbox Code Playgroud)
排序后,currentItems中的LogEvent对象未正确排序.我很确定我的运算符重载正在工作.
当我做这样的事情:
std::cout << currentItems[0]<=currentItems[1]?"T":"F";
Run Code Online (Sandbox Code Playgroud)
它会输出正确的值.
那么我做错了什么,我该如何纠正呢?
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.
Run Code Online (Sandbox Code Playgroud)
ETA:为了有一个完整的答案接受,我将从这里的其他答案中剔除一些好的部分.
首先,定义一个小于运算符的标准语法:
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.
// ...
}
Run Code Online (Sandbox Code Playgroud)
LogEvent.cpp
bool LogEvent::operator<(const LogEvent &event) {return timestamp<event.timestamp;}
Run Code Online (Sandbox Code Playgroud)
完成后,您可以使用此模板取消引用 - 并从leemes的答案中进行比较:
template<class T>
bool dereferencedLessThan(T * o1, T * o2) {
return *o1 < *o2;
}
Run Code Online (Sandbox Code Playgroud)
像这样排序你的列表:
QVector<LogEvent *> currentItems;
//add a bunch of LogEvent objects to currentItems
qSort(list.begin(), list.end(), dereferencedLessThan<LogEvent>);
Run Code Online (Sandbox Code Playgroud)
为了完整起见,为所有比较定义标准语法比较运算符将是一种很好的形式.您是否保留非标准比较运算符取决于您.
你可以定义一个带有两个(通用)指针的比较函数:
template<class T>
bool dereferencedLessThan(T * o1, T * o2) {
return *o1 < *o2;
}
Run Code Online (Sandbox Code Playgroud)
然后打电话
void qSort(RandomAccessIterator begin,RandomAccessIterator end,LessThan lessThan)
像这样:
qSort(list.begin(), list.end(), dereferencedLessThan<LogEvent>);
Run Code Online (Sandbox Code Playgroud)
然后,您可以将此方法用于其他类型,而无需定义多个函数.