是否允许指针作为有序STL容器中的键?

时间:2011-02-06 12:07:14

标签: c++ pointers standards containers

C ++标准版有this other question asking about how comparing pointers is supposed to be interpreted

所以我想知道C ++ Std在有序标准库(STL)容器中使用指针作为键的含义是什么 - 也就是说允许有

std::map<T1*, T2>

这是由于std::lessbuiltin operator <

的规范

4 个答案:

答案 0 :(得分:11)

是的,因为它使用std::less,即使<没有,也需要导致总订单。 (<将被允许将不同序列中的不同指针视为相等,如果插入来自不同序列的指针,则会导致map等的奇怪行为。)

答案 1 :(得分:3)

我想补充另一个不这样做的理由。如果您以这种方式使用指针,并且如果您碰巧有一个错误取决于容器元素的排序,那么将很难找到。即使你的程序看起来完全是确定性的,也不会。容器中元素的顺序取决于内存分配器使用的算法,这完全超出您的控制范围。如果您在不重新启动程序的情况下运行相同的多个时间示例,则有些可能会失败而其他人会成功。

这是痛苦经历的声音。我用一个调试器项目做了一次,我用容器填充了C ++符号。当我需要对符号进行排序时,我最终得到了不同的符号,但它们具有相同的名称(想想重载的函数),并且在所有其他方面都是相同的。因此,在这种情况下,我通过符号对象的地址将它们作为最后的手段进行比较。我遇到了几个明显不确定的错误,其中非确定性只是由这种现象引起的。有时需要超过10次或15次尝试来重现问题。我最终花了很多时间来消除地址排序,从长远来看,这给我带来了很多麻烦。

话虽如此,我不会说我最近没有这样做过。但每次我这样做,我觉得这是一个错误。

答案 2 :(得分:0)

“他们可能有效但不”是我给出的答案。

显然,你提出的可比性问题,但你不想要的原因是因为缺乏对“香草”指针的参考管理。在没有将对象从容器中删除的情况下删除对象非常容易,导致下次访问时会出现无效指针和访问冲突。

答案 3 :(得分:-3)

是。指针可通过运算符&lt;()进行比较。

如果指针没有指向同一个数组的元素或同一个对象中的元素,那么c ++标准表示行为未指定[expr.rel]。

标准表示未指定的行为意味着它的实现已定义[defns.unspecified]。

如果您的编译器保证严格的弱指针顺序,您可以使用任何带有关联容器的指针。

大多数编译器通过比较内存地址来进行指针比较。在大多数架构中,这种比较形成了严格的弱秩序。

因此,使用指针作为键是安全的。