使用 protobuf 对象作为 std::map 中的键

Using protobuf objects as key in the std::map

本文关键字:map std protobuf 对象 使用      更新时间:2023-10-16

我是协议缓冲区概念的新手,手头有一个任务,如果我使用 protobuf 对象作为std::map中的键,就可以解决。

我知道要使用 protobuf 对象作为键,我需要为std::map提供一个自定义比较器来维护键的顺序。

我现在有两个问题:

在google/protobuf/
  1. util中是否有任何实用程序函数/类比运算符重载更少,用于比较两个protobuf消息?即与此类似的东西。
bool operator<(google::protobuf::Message m1, google::protobuf::Message m2){
// compare the protobuf messages
// and finally return the value
return value;
} 
  1. 我可能意识到的任何潜在副作用,可能是由于使用 protobuf 对象作为键而产生的?

如果您不关心顺序,我建议最好使用std::unordered_map而不是std::map。这不仅是最佳的,而且不易出错。在比较器实现的情况下,您必须确保Message m1是否大于Message m2并且Message m2大于Message m3,则Message m1大于Message m3。(提到,因为我从你的定义中不清楚)。

您可以使用 MessageDifferencer 作为std:equal_to的替代品。另请参阅谷歌协议缓冲区比较的答案

但是,正如您正确指出的那样,没有等效于std::hash,您将需要提供自定义哈希函数。请参阅 PR-2066 和 PR-2304,其中讨论了此缺失的功能。

从拉取请求中,引用 xfxyjwf:

使用 proto 消息作为键不是一个好主意,因为它们不是真正的值类型。由于存在未知字段,一个二进制文件中的两个相等消息可能会被另一个二进制文件视为不同,因此即使给定完全相同的输入数据,两个不同的二进制文件也可能获得两个不同的unordered_map<>(如果使用 MessageDifferencer 实现哈希函数)。最好编写自己的哈希函数,该函数具有您想要的行为,而不是回复通用的哈希函数。

如果您没有未知字段,则通用哈希函数应该可以正常工作。

相关文章: