简体   繁体   中英

Using protobuf objects as key in the std::map

I'm new to the concept of protocol buffers and have a task at hand that can be resolved if I use the protobuf object as keys in the std::map .

I know to be able to use protobuf object as key, I need to provide a custom comparator to the std::map to maintain the ordering of the keys.

I have two questions at this point in time:

  1. Is there any utility function/class in the google/protobuf/util that overloads less than operator for comparing two protobuf messages? ie, something similar to this.
bool operator<(google::protobuf::Message m1, google::protobuf::Message m2){
    // compare the protobuf messages
    // and finally return the value
    return value;
} 
  1. Any potential side effects that I might be aware of, which might arise as a result of using a protobuf object as key?

I suggest it's better to use std::unordered_map rather than std::map if you don't care about the order. This is not only optimal but also less error prone. In case of the comparator implementation, you will have to make sure if Message m1 is greater than Message m2 and Message m2 is greater than Message m3 , then Message m1 is greater than Message m3 . (mentioning since this wasn't clear to me from your definition).

You can use the MessageDifferencer as a replacement to std:equal_to . See also answers at Google protocol buffers compare

However, as you correctly point out that there is no equivalent to std::hash , you will need to provide a custom hash function. Please refer to PR-2066 and PR-2304 which discuss about this missing functionality.

From the pull request, quoting 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.

If you don't have unknown fields, a generic hash function should work fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM