Qt:qSort 而不使用复制构造函数
Qt: qSort without using the copy constructor
据我了解快速排序,如果成员的洗牌是用复制ctor完成的,你会对O(n lnn(的真正含义感到非常失望。所以我决定qSort
用
QList<QObject> mylist; //Yes, I know this isn't feasible, I just wanted to find where the copy ctor is being used
qSort(list);
并被那些击中
'QObject::QObject(const QObject&(' 是私有的
错误。据我所知,问题始于begin()
方法,因为如果我有
list.begin();
编译器错误指示此 qList.h 行以某种方式尝试使用复制 CTOR:
inline void detach() { if (d->ref != 1) detach_helper(); }
我意识到我可以制作列表的成员指针,然后实现lessThan
函数,但这对于这个代码库来说不是很方便。那么,当qSort
对对象列表进行操作时,如何避免使用复制 ctor呢?
我在 Linux 64 位和 32 位上使用 Qt 4.8。
我会试一试,因为我不是Qt用户。
通常,如果需要对无法复制的对象列表进行排序,或者复制方面成本很高,则一种解决方法是对索引列表而不是数据进行排序,并在排序完成后,使用索引列表访问数据。
根据QtqSort
的文档,使用上述方法可能会工作:
int doSomething()
{
QList<QObject> myList;
//...
QVector<int> index(myList.size());
for (int i = 0; i < myList.size(); ++i ) index[i] = i;
qSort(index.begin(), index.end(), [](int n1, int n2) { return myList[n1] < myList[n2];});
}
完成此操作后,您可以通过以下方式访问已排序的myList
容器:
myList[index[0]]; // First item
myList[index[1]]; // second item
...
注意:我假设qSort
接受lambda函数作为第三个参数。 如果存在问题,可以使用函数对象。
QObject 既没有复制构造函数,也没有赋值运算符。这是设计使然。
http://doc.qt.io/qt-4.8/qobject.html#no-copy-constructor-or-assignment-operator
因此,您不能qSort
包含QObject
s 或派生类的容器,至少在 C++11 之前不能C++。您可以尝试在编译器中打开C++11支持(或更高版本((并确保Qt库也使用该支持进行编译(;如果Qt人员像往常一样好,那么在这种情况下,他们正在使用移动语义。
否则,使用指针或像QSharedPointer
这样的Qt指针类之一将是一种有效的方法。无论如何,如果您不希望按内存地址排序,则需要一个lessThan
运算符或函数。
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 复制构造函数、赋值运算符C++
- std::ofstream 作为类成员删除复制构造函数?
- 复制构造函数C++无法正确复制指针
- 关于复制构造函数的一个棘手问题
- 为什么调用复制构造函数而不是移动构造函数?
- 填充上编译器生成的复制构造函数之间的不一致
- C++ 对象指针数组的复制构造函数
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 防止在复制构造函数中隐式调用基构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 具有已删除移动和复制构造函数的类的就地构造
- 复制构造函数隐式转换问题
- 复制构造函数中的递归调用