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

Using protobuf objects as key in the std::map

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

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

此时我有两个问题:

  1. google/protobuf/util 中是否有实用程序 function/class 重载 less than 运算符来比较两个 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 m2Message m2 大于 Message m3,则 Message m1 大于比 Message m3。 (提到因为根据你的定义我不清楚)。

您可以使用 MessageDifferencer as a replacement to std:equal_to. See also answers at Google protocol buffers compare

但是,正如您正确指出不存在 std::hash 的等效项一样,您将需要提供自定义哈希函数。请参阅讨论此缺失功能的 PR-2066 and PR-2304

来自拉取请求,引用 xfxyjwf:

It's not a very good idea to use proto message as keys because they are not true value types. With the presence of unknown fields, two equal messages in one binary might be treated as different by another, and therefore two different binaries might get two different unordered_map<> even given the exactly same input data (if the hash function is implemented using MessageDifferencer). It's probably better to write your own hash function that has your desired behavior rather than replying on a generic one.

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