Pippi
Pippi

Reputation: 2571

How can I overload the compare operator for a set of pairs?

How can I overload and pass a < (less than) comparator to a set of pairs of integers? This is my current code:

class A{
public:
    typedef std::pair<int, int> pair_type;  

    bool operator<(const pair_type& a, const pair_type& b){ 
        if (a.first < b.first) return true;
        else if ( (a.first == b.first) && (a.second < b.second) ) return true;
        else return false;
    }

private:
    std::set< pair_type > edge_;
};

If I try to compile this code, then I get the following error:

error: 'bool A::operator<(const pair_type&, const pair_type&)' must take exactly one argument

How can I fix it?

Upvotes: 3

Views: 15177

Answers (4)

honk
honk

Reputation: 9743

Since C++11, you can also use a lambda expression instead of defining a comparator struct:

using pair_type = std::pair<int, int>;

auto comp = [](const pair_type& a, const pair_type& b) {
    return (a.first < b.first) || ((a.first == b.first) && (a.second < b.second));
};

I also compacted your comparator code in order to save two lines. Now, you can define your set in the following way:

std::set<pair_type, decltype(comp)> edge_(comp);

However, if you want to use the above comparator for a set which is a class member, then it's a bit less comfortable, because you have to pass the comparator also to the constructor of the set, as shown above. This means, you have to hand over the comparator in the initializer list of the constructor definition:

class A{
public:
    A() : edge_(comp) {}

private:
    std::set<pair_type, decltype(comp)> edge_;
};

Code on Ideone

Upvotes: 2

smossen
smossen

Reputation: 887

class A{
public:
    typedef std::pair<int, int> pair_type;  

    struct compare {
        bool operator()(const pair_type& a, const pair_type& b) {
          if (a.first < b.first) return true;
          else if ( (a.first == b.first) && (a.second < b.second) ) return true;
          else return false;
        }   
    };

  private:
    std::set<pair_type, compare> edge_;
};

Upvotes: 7

Derek
Derek

Reputation: 108

You should be definining the operator overload as a class member (with a single parameter, usually another instance of the same class):

class pair_type : public std::pair<int, int>
{
public:
    bool operator<(const pair_type &comp) const
    {
        if (this->first < comp.first) return true;
        else if ( (this->first == comp.first) && (this->second < comp.second) ) return true;
        else return false;
    }
};

Upvotes: 5

ForEveR
ForEveR

Reputation: 55887

Your operator should be free function (not member-function), since it has no any relations to A class.

Upvotes: 2

Related Questions