如何比较两个联合的排序
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
是一个联合,我不确定如何将它与另一个它的类型进行比较,这种方式与上次分配的联合成员无关(小于运算符中的开关太贵了)
排序并不重要,重要的是地图将不同的值视为不同的值。有没有办法对两个联合进行快速位比较?
不,不能进行与类型无关的字节比较。 thing2
和 thing3
有不同的字节数参与它们的值(即不同的填充量),因此您不能使用 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->data
和 rh.data
的 2 个实例可以使用与比较 this->type
和 rh.type
相同的方式使用普通关系运算符进行比较
同理,B,Q,Y在逻辑上应该是相等的weight/priority/valuew.r.t比较。 things1, thing2, thing3 的其他对应值也一样。
我有一个 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
是一个联合,我不确定如何将它与另一个它的类型进行比较,这种方式与上次分配的联合成员无关(小于运算符中的开关太贵了)
排序并不重要,重要的是地图将不同的值视为不同的值。有没有办法对两个联合进行快速位比较?
不,不能进行与类型无关的字节比较。 thing2
和 thing3
有不同的字节数参与它们的值(即不同的填充量),因此您不能使用 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->data
和 rh.data
的 2 个实例可以使用与比较 this->type
和 rh.type
相同的方式使用普通关系运算符进行比较
同理,B,Q,Y在逻辑上应该是相等的weight/priority/valuew.r.t比较。 things1, thing2, thing3 的其他对应值也一样。