Search code examples
c++comparatormultimap

C++: multimap custom comparator for object keys


Can I somehow use my own function for ordering the pairs in multimap? I have three classes CTimeStamp, CMail and CMailLog. And the thing is in the CMailLog I have multimap<CTimeStamp, CMail> which I use because for this task I need solution which will be very fast for huge amounts of data and therefor I would need to somehow use method Compare from CTimeStamp when inserting into this multimap. The classes look something like this.

class CTimeStamp {
   public:
     int compare (const CTimeStamp &x) const;
     ...
}
class CMail {
   ...
}
class CMailLog {
   public:
     ...
   private:
     multimap<CTimeStamp, CMail> logs;
}

I'm not sure how to do this or if it's even possible.


Solution

  • I would need to somehow use method Compare from CTimeStamp when inserting into this multimap

    As from the std::multimap documentation, all you need is to either

    • provide a specialisation for std::less<CTimeStamp>

      namespace std {
          bool less<CTimeStamp>(const CTimeStamp& a, const CTimeStamp& b) {
              return a.compare(b) < 0;
          }
      }
      

    or

    • provide a custom comparator at the constructor:

      CMailLog() : 
          logs([](const CTimeStamp& a, const CTimeStamp& b) { return a.compare(b) < 0; }) 
      {}
      

    I used a lambda expression in my last example for the constructor as I consider that's the shortest and most comprehensible form.
    In fact any callable with the signature bool (const CTimeStamp&,const CTimeStamp&) would fit well.

    You might also write a simple global function

    bool foo(const CTimeStamp& a,const CTimeStamp& b) {
        return a.compare(b) < 0;
    }
    

    or appropriate callable type

    struct foo {
        bool operator()(const CTimeStamp& a,const CTimeStamp& b) {
            return a.compare(b) < 0;
        }
    };
    

    and pass that one at the

    multimap<CTimeStamp, CMail> logs;
    

    in the constructor initializer list:

    CMailLog() : logs(foo) {}
    

    Callable struct version

    CMailLog() : logs(foo()) {}