如何比较两个工会的订购

时间:2016-05-06 08:45:26

标签: c++ dictionary unions

我有一个类作为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是一个联盟,我不确定如何将它与另一个类型进行比较,其方式与上次分配的联盟成员无关(在lessthan运算符中的一个开关将是太昂贵了)

排序并不重要,重要的是地图会看到不同的值不同。有没有办法在两个联合上进行快速比较?

2 个答案:

答案 0 :(得分:1)

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

如果类型从0连续运行(或者无论如何都是相当小的数字),那么您可以查找一个大小来比较由type索引的数组,提供所有联合成员中的所有填充都在最后,这样参与该值的所有字节都在开头。如果thing3大于boolint16 Enumerator... etc ...

,则type已经可能无法通过此测试

理论上,您可以使用由std::unordered_map索引的函数指针数组来避免切换。但是,一旦优化器完成其工作,没有特别的理由期望它比开关更快。一般来说,函数指针是内联的死亡,因此它们削弱了优化器和CPU自己的推测性指令获取/执行。

顺便说一句,如果您不关心订单,那么std::map通常会比{{1}}表现得更好,但是您仍然需要编写一个只需要编写哈希函数的问题哈希参与该值的字节。

答案 1 :(得分:1)

此解决方案需要修改union以及union成员可以采用的值的位置条件。请注意:这可能不是必需的答案,但可以比较上次分配的工会成员的不可知性。

使union的每个成员都具有相同的规模。无论如何,会考虑成员的最大尺寸,因此具有相同的尺寸无关紧要。 现在决定成员的值域。 让我们说:

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

现在,如果您可以确保A,P,X在逻辑上等于权重/优先级/值,那么可以使用正常关系比较union this->datarh.data的2个实例运算符与您比较this->typerh.type的运算符相同 类似地,B,Q,Y应该在逻辑上等于权重/优先级/值w.r.t比较。同样适用于thing1,thing2和thing3的其他对应值。