我怀疑这些限制应该被视为指关系对实际用作键的值的行为,而不一定是针对该类型的所有值。目前没有时间通过标准寻找引用实际容器元素而不是该类型的所有值的“确凿证据”语言。
类似的情况:如果比较器(用于指针或智能指针的容器)调用虚函数,并且有人链接它所比较类型的派生类,这会以某种方式覆盖虚函数,使比较器不是严格的弱函数,该怎么办命令?即使没有人真正使用该派生类,程序是否也会变得未定义?
如果有疑问,您可以使用严格弱阶比较器来支持 NaN:
bool operator()(double a, double b) {
if ((a == a) && (b == b)) {
return a < b;
}
if ((a != a) && (b != b)) return false;
// We have one NaN and one non-NaN.
// Let's say NaN is less than everything
return (a != a)
}
最后两行“优化”为return (b == b);
,尽管我不确定评论是否会随之优化。
我认为托马拉克已经说服了我,该语言确实表明整个类型都需要订购。
这没有什么意义,因为地图不会凭空产生值,它只使用给定的值(及其副本),但问题是关于规则,据我所知,它们是规则。 C++0x 是一样的。我想知道是否有缺陷报告,或者是否有任何提交缺陷报告的地方。
这也很烦人,因为在(非常罕见的)系统上std::less
对于指针来说很慢,你can't use <
作为指针映射中的比较器,即使您知道指针都指向同一数组的元素。耻辱。
另一种选择是使用以下类作为键类型,因此仅在进入映射时检查键是否为 NaN,而不是在上面的每次比较时检查键。
struct SaneDouble {
double value;
SaneDouble (double d) : value(d) {
if (d != d) throw std::logic_error();
}
static friend bool operator<(SaneDouble lhs, SaneDouble rhs) {
return lhs.value < rhs.value;
}
// possibly a conversion to double
};
这提出了另一个问题——显然有人可以创建一个SaneDouble
然后设置它的value
NaN(假设实现允许他们从某处获取一个而不崩溃)。那么“SaneDouble 的元素”是否是严格弱序的?我半心半意地尝试在构造函数中创建一个类不变量是否会使我的程序未定义,即使没有人真正破坏该不变量,仅仅是因为他们could因此这样做的结果是“SaneDouble 的元素”?当且仅当定义程序的行为时,这真的是标准的意图吗?value
被标记private
?该标准实际上是否在任何地方定义了类型的“元素”?
我想知道我们是否应该将“Key 的元素”解释为比较器对 Key 的某些元素产生严格的弱顺序。大概包括实际使用的。 “我有甜甜圈”并不意味着我有every油炸圈饼。不过,这有点牵强。