Chaining of ordering predicates (e.g. for std::sort)

前端 未结 6 1826
说谎
说谎 2021-02-05 23:33

You can pass a function pointer, function object (or boost lambda) to std::sort to define a strict weak ordering of the elements of the container you want sorted.

Howeve

6条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-06 00:32

    You could build a little chaining system like so:

    struct Type {
      string first, last;
      int age;
    };
    
    struct CmpFirst {
      bool operator () (const Type& lhs, const Type& rhs) { return lhs.first < rhs.first; }
    };
    
    struct CmpLast {
      bool operator () (const Type& lhs, const Type& rhs) { return lhs.last < rhs.last; }
    };
    
    struct CmpAge {
      bool operator () (const Type& lhs, const Type& rhs) { return lhs.age < rhs.age; }
    };
    
    template 
    struct Chain {
      Chain(const First& f_, const Second& s_): f(f_), s(s_) {}
    
      bool operator () (const Type& lhs, const Type& rhs) {
        if(f(lhs, rhs))
          return true;
        if(f(rhs, lhs))
          return false;
    
        return s(lhs, rhs);
      }
    
      template 
      Chain  chain(const Next& next) const {
         return Chain  (*this, next);
      }
    
      First f;
      Second s;
    };
    
    struct False { bool operator() (const Type& lhs, const Type& rhs) { return false; } };
    
    template 
    Chain  make_chain(const Op& op) { return Chain  (False(), op); }
    

    Then to use it:

    vector  v;  // fill this baby up
    
    sort(v.begin(), v.end(), make_chain(CmpLast()).chain(CmpFirst()).chain(CmpAge()));
    

    The last line is a little verbose, but I think it's clear what's intended.

提交回复
热议问题