带有 std::map<T*, U> 的程序是否具有明确定义的行为?

Lig*_*ica 14 c++ sorting pointers language-lawyer strict-weak-ordering

比较指向不相关对象的指针具有未指定的结果。

这似乎表明该程序可能具有未定义的行为,至少因为我们不能保证键类型的严格弱排序:

#include <map>

int main()
{
    int x = 0, y = 1;
    bool arbitrary = false;

    std::map<int*, bool> m{
       {&x, arbitrary},
       {&y, arbitrary}
    };
}
Run Code Online (Sandbox Code Playgroud)

更一般地说,我们可以说带有指针键的映射是一个危险的*命题吗?或者有什么特别的规则我们可以依靠?

* 从学术上讲,即;实际上,我不知道主流实现实际上会在比较任意指针时引发地狱。

Hol*_*olt 17

是的,因为std::map默认比较运算符是std::less,与标准比较运算符不同,它完全是为指针类型定义的。

[比较#2]

对于模板less、greater、less_equal 和greater_equal,任何指针类型的特化产生的结果与实现定义的严格指针全序( [defns.order.ptr] ) 一致。

过度的指针实现定义的严格的总顺序定义在[defns.order.ptr]为:

实现定义的对所有指针值的严格总排序,以便排序与内置运算符 <、>、<=、>= 和 <=> 强加的偏序一致


Jar*_*d42 8

std::less ( 的默认比较器std::map) 对指针有特殊处理,允许:

的专业化std::less任何指针类型得到了严格的全序,即使内置的operator<没有。

而关于

我们可以说带有指针键的映射是一个危险的命题吗?

所以总体来说没问题。

应该对const char*钥匙采取额外的预防措施:

我们比较的是指针而不是字符串内容(主要是初学者的困惑)。

具有相同内容的 C 字符串文字不能保证等于:

"literal" == "literal"; // Not guaranteed
"literal" < "literal"; // false .. or true
Run Code Online (Sandbox Code Playgroud)