如何比较两个联合的排序

How to compare two unions for ordering

我有一个 class 用作 map 密钥,其中包含两个成员

struct Key{
    unsigned int type;
    union{
        Enumerator thing1;
        int32 thing2;
        struct{int16 a; bool b;} thing3;
        ... etc...
    }data;

    bool operator<(const Key & rh) const{
        if(type == rh.type){
            ???
        }else{
            return type < rh.type;
        }
    }
}

第二个成员 data 是一个联合,我不确定如何将它与另一个它的类型进行比较,这种方式与上次分配的联合成员无关(小于运算符中的开关太贵了)

排序并不重要,重要的是地图将不同的值视为不同的值。有没有办法对两个联合进行快速位比较?

不,不能进行与类型无关的字节比较。 thing2thing3 有不同的字节数参与它们的值(即不同的填充量),因此您不能使用 std::memcmp 或任何其他原始内存比较。

如果类型 运行 从 0 开始连续(或者无论如何,都是相当小的数字),那么您也许可以从 type、[=30 索引的数组中查找要比较的大小=]提供所有联合成员中的所有填充都在末尾,这样所有参与该值的字节都在开头。如果 bool 大于 int16,并且我们不知道 Enumerator... etc ...

中的内容,thing3 可能已经无法通过此测试

理论上,您可以使用由 type 索引的函数指针数组来避免切换。但是,一旦优化器完成其工作,就没有特别的理由期望它比 switch 更快。一般来说,函数指针对内联来说是致命的,因此它们会削弱优化器和 CPU 自己的推测指令 fetching/execution.

顺便说一句,如果你不关心顺序那么std::unordered_map通常会比std::map表现得更好,但你仍然会有这个问题需要写一个散列函数仅散列参与值的字节。

此解决方案需要修改 union 以及 union 成员可以采用的值的位置条件。请注意:这可能不是必需的答案,而是一种可能的比较方法,它与上次分配的工会成员无关。

使 union 中的每个成员大小相同。因为无论如何,将考虑成员的最大大小,所以大小相同并不重要。 现在决定成员的价值域。 比方说:

  • thing1 的域是 {A,B,C....}
  • thing2 的域是 {P,Q,R....}
  • thing3 的域是 {X,Y,Z....}

现在,如果您可以确保 A、P、X 在逻辑上相等 weight/priority/value w.r.t 比较,那么 union this->datarh.data 的 2 个实例可以使用与比较 this->typerh.type 相同的方式使用普通关系运算符进行比较 同理,B,Q,Y在逻辑上应该是相等的weight/priority/valuew.r.t比较。 things1, thing2, thing3 的其他对应值也一样。