Ker*_* SB 22 c++ pointers predicate standard-library
通常只能比较C++中的指针是否相等.相比之下,只有指向同一完整对象(例如数组元素)的子对象的两个指针才允许小于比较.
因此T * p, * q,评估一般是非法的p < q.
标准库包含函数类模板std::less<T>等,它包含内置运算符<.但是,标准有关于指针类型(20.8.5/8)的说法:
对于模板
greater,less,greater_equal,和less_equal,对于任何指针类型的专业化产生总订单,即使内置的运营商<,>,<=,>=没有.
怎么能实现呢?甚至可以实现这个吗?
我看了看GCC 4.7.2和3.2锵,不包含任何的指针类型专业化的.它们似乎依赖于<在所有支持的平台上无条件地有效.
Jam*_*nze 16
指针可以完全排序吗?不是便携式标准C++.这就是为什么标准要求实施来解决问题,而不是你.对于指针的任何给定表示,应该可以定义任意总排序,但是如何执行它将取决于指针的表示.
对于具有平坦地址空间和字节寻址的机器,只需将指针视为类似大小的整数或无符号整数就足够了; 这就是大多数编译器在一个对象中处理比较的方式,所以在这样的机器上,库不需要专门化std::less等等."未指明"的行为恰好是做正确的事情.
对于单词寻址机器(并且至少有一个仍在生产中),可能需要将指针转换void*
为编译器本机比较之前的工作.
对于具有分段架构的机器,可能需要做更多的工作.在这样的机器上通常要求阵列完全在一个段中,并且只是比较段中的偏移量; 这意味着如果
a并且b是两个任意指针,你可能最终得到!(a < b) &&
!(b < a)但不是a == b.在这种情况下,编译器必须std::less<>为指针提供et al的特化,它(可能)从指针中提取段和偏移量,并对它们进行某种操作.
编辑:
或许值得一提的是:C++标准中的保证仅适用于标准C++,或者在本例中,是从标准C++获得的指针.在大多数现代系统中,mmap
相同文件到两个不同的地址范围相当容易,并且有两个指针p
,q它们比较不相等,但指向同一个对象.
R. *_*des 10
是否可以在指针不形成全局总订单的目标上实现标准库?
是.给定任何有限集,您始终可以在其上定义任意总订单.
考虑一个简单的示例,其中您只有五个可能的不同指针值.让我们把这些O(为nullptr),γ,ζ,χ,ψ 1.
假设可以比较四个非空指针中的两个不同指针的对<.我们可以简单地随意说std::less给我们这个顺序:Oζγψχ,即使<没有.
当然,以有效的方式实现这种任意排序是实现质量的问题.
1我正在使用希腊字母来消除由于熟悉拉丁字母而产生的潜意识的秩序概念; 我向知道希腊字母顺序的读者道歉
在大多数具有平坦地址空间的平台上,它们可以简单地在指针之间进行数值比较。在无法做到这一点的平台上,实现者必须想出一些其他方法来建立使用 in 的总顺序std::less,但他们可能会使用更有效的方法 for <,因为它的保证较弱。
在GCC和锵的情况下,就可以实现std::less的<,只要它们提供了更强的保障<。由于他们是为 实现行为的人<,因此他们可以依赖此行为,但他们的用户不能,因为将来可能会发生变化。
问题是分段架构,其中内存地址有两部分:段和偏移量。将这些部分转换为某种线性形式“足够容易”,但这需要额外的代码,并且决定不为operator<. 对于分段架构,operator<可以简单地比较偏移量。早期版本的 Windows 存在此问题。
请注意,“足够简单”是系统程序员的观点。不同的段选择器可以引用相同的内存块,因此产生规范排序需要仔细研究段映射的细节,这取决于平台并且很可能很慢。