qsort 在C++中不适用于哪些类型
What kinds of types does qsort not work for in C++?
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 四重奏可以具有指向其父级的节点。可以想象,调试任何容器的迭代器都可能包含指向容器的指针。要做你想做的事情,你必须(至少(排除在其实现的任何部分存在任何指向容器的指针,而像"没有实现使用这些技巧"这样的笼统声明是非常不明智的。制定标准的全部意义在于对所有符合标准的实现做出陈述,所以如果你没有从标准中推断出你的结论,那么即使你的陈述今天是正确的,明天也可能变得不真实。
- FLTK 2.0构建和演示,适用于VS2019的2011年左右的代码库
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 适用于 WebView2 旧版本的示例应用程序
- 在 NVIDIA GEFORCE GTX 1050 上下载适用于 Windows 10 的 openCL 1.2
- __attribute__(优化(0))) 是否适用于"recursively"?
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 使用一个参数的模板函数时出错(适用于 2)
- 将 2D 矢量转换为 C 类型的最佳方法(适用于 SGX 飞地)
- OpenCL 的 clEnqueueReadBufferRect 适用于 int 但不适用于 double 数据类型
- 声明适用于 auto,但不能显式声明类型?
- 无法获得 boost::spirit parser&lexer 适用于 std::string 或 int 或 double 以外的令牌类型
- 为什么模板函数只基于返回类型适用于C++
- CRC计算模板适用于除CRC8以外的所有类型
- 哪些适用于 Windows 的 C++11 编译器支持新的类型特征,如"is_nothrow_move_constructible"?
- 类模板仅适用于2种类型
- 模板的类型定义包括char[][] - 适用于VS2008,但不适用于gcc
- 适用于Microsoft Visual C++2008和R2007b的Mex类型
- sizeof 如何适用于 int 类型
- 适用于 C、C++ 或 .NET 的"Sparse Map"数据类型(类似 RLE)