qsort 在C++中不适用于哪些类型

What kinds of types does qsort not work for in C++?

本文关键字:类型 适用于 不适用 C++ qsort      更新时间:2023-10-16
std::sort使用

std::swap 交换元素,而 又使用复制构造函数和赋值运算符,保证在交换值时获得正确的语义。

qsort通过简单地交换元素的基础位来交换元素,忽略与要交换的类型关联的任何语义。

尽管qsort不知道您正在排序的类型语义,但它仍然非常适用于非平凡类型。如果我没记错的话,它将适用于所有标准容器,尽管它们不是 POD 类型。

我想qsort在类型T上正常工作的先决条件是T是/平凡可移动/的。在我的头顶上,唯一不能移动的类型是那些有内部指针的类型。例如:

struct NotTriviallyMovable
{
    NotTriviallyMovable() : m_someElement(&m_array[5]) {}
    int m_array[10];
    int* m_someElement;
};

如果你对一个NotTriviallyMovable数组进行排序,那么m_someElement最终会指向错误的元素。

我的问题是:还有哪些类型不适用于qsort

任何不是 POD 类型的类型都不能与 qsort() 一起使用。如果您考虑 C++0x,可能会有更多类型可用于 qsort(),因为它会更改 POD 的定义。如果您打算将非 POD 类型与qsort()一起使用,那么您就处于 UB 的土地上,守护进程会从您的鼻子里飞出来。

这也适用于具有指向"相关"对象的指针的类型。这样的指针有许多与"内部"指针相关的问题,但要准确证明"相关"对象是什么要困难得多。

特定类型的"相关"对象是带有反向指针的对象。如果对象 A 和 B 是位交换的,并且 A 和 C 相互指向,那么之后 B 将指向 C,但 C 将指向 A。

你完全错了。任何与qsort一起工作的非 POD 类型都是完整的,完全是运气。仅仅因为它碰巧在你的平台上为你工作,你的编译器在蓝月亮上,如果你把处女的血献给众神并先跳个小舞,并不意味着它真的有效。

哦,这是另一个用于非微不足道的可移动类型,其实例是外部观察的。您移动了它,但不通知观察者,因为您从未调用过交换或复制构造函数。

"如果我没记错的话,它将适用于所有标准容器">

整个问题归结为,在什么实施中?您是要按照标准进行编码,还是要按照您今天面前的编译器的实现细节进行编码?如果是后者,那么如果你所有的测试都通过了,我想它会起作用。

如果您询问的是C++编程语言,则需要qsort仅适用于 POD 类型。如果您询问的是特定的实现,是哪一个?如果你问的是所有的实现,那么你就错过了机会,因为这种稻草民意调查的最佳地点是C++0x工作组会议,因为他们聚集了几乎每个组织的代表,并积极维护C++实现。

对于它的价值,我可以很容易地想象一个std::list的实现,其中列表节点嵌入在列表对象本身中,并用作头/尾哨兵。我不知道什么实现(如果有的话(实际上这样做,因为使用空指针作为头/尾哨兵也很常见,但当然实现双链表有一些优点在两端都有一个虚拟节点。这种std::list的实例当然不会是微不足道的,因为它的第一个和最后一个元素的节点将不再指向哨兵。它的swap实现和(在 C++0x( 中(它的移动构造函数将通过更新这些第一个和最后一个节点来解释这一点。

没有什么可以阻止您的编译器在其下一个版本中切换到此 std::list 实现,尽管这会破坏二进制兼容性,因此考虑到大多数编译器的管理方式,它必须是一个主要版本。

类似地,map/set/multimap/multiset 四重奏可以具有指向其父级的节点。可以想象,调试任何容器的迭代器都可能包含指向容器的指针。要做你想做的事情,你必须(至少(排除在其实现的任何部分存在任何指向容器的指针,而像"没有实现使用这些技巧"这样的笼统声明是非常不明智的。制定标准的全部意义在于对所有符合标准的实现做出陈述,所以如果你没有从标准中推断出你的结论,那么即使你的陈述今天是正确的,明天也可能变得不真实。