# Pair coupled with operator overload to insert into kit

I am trying to add `pair<int,int>`

to a set. If a pair has the same two values ​​as the others in the set, it should not be inserted.

Here's my non-working code:

``````typedef  std::pair<int, int> PairInt;

template<>
bool std::operator==(const PairInt& l, const PairInt& r)
{
return (l.first == r.first && l.second == r.second) ||
(l.first == r.second && l.second == r.first);
}

int main()
{
std::set<PairInt> intSet;
intSet.insert(PairInt(1,3));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(4,1));
}
```

```

The pair (4,1) is currently being added, although there is already a (1,4) pair. The final contents of the set are:

``````(1 3)
(1 4)
(4 1)
```

```

and I want him to be

``````(1 3)
(1 4)
```

```

I tried to put breakpoints in the overloaded method, but they are never hit. What I did wrong?

+3

source to share

The comparison should determine if the first element is less than the second. This is how it should be:

``````namspace std
{
template<>
bool operator < (const PairInt& l, const PairInt& r)
{
//swap only if they're unequal to avoid infinite recursion
if (l.first != l.second)
{
//swap elements, considering your special case
if (l.first == r.second && l.second == r.first)
return l < PairInt(r.second, r.first); //call again!
}

//actual comparison is done here
if ( l.first != r.first )
return l.first < r.first;
else
return l.second < r.second;
}
}
```

```

It now gives the desired output:

``````1,3
1,4
```

```

Watch an online demo .

Note that the following comparison function is: Strict weak ordering

0

source

Sets are based on `operator<`

(ordering / equivalence relation), not `operator==`

(which is an equality relation).

To do what you are trying to do, use a custom comparator:

``````#include <set>
#include <utility>
#include <cassert>
typedef std::pair<int, int> PairInt;
PairInt normalize(const PairInt& p) {
return p.second < p.first ? PairInt(p.second, p.first) : p;
}
struct Comparator {
bool operator()(const PairInt& l, const PairInt& r) const {
//Compare canonical forms of l and r.
return normalize(l) < normalize(r);
}
};

int main()
{
std::set<PairInt, Comparator> intSet;
intSet.insert(PairInt(1,3));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(4,1));
assert(intSet.size() == 2);
}
```

```
+3

source

You will need to provide a comparison function to view one element less than the other, not to determine if they are equal. Here's a complete example:

``````#include <utility>
#include <algorithm>
#include <set>
#include <iostream>

typedef  std::pair<int, int> PairInt;
typedef bool Compare(const PairInt &,const PairInt &);

bool compare(const PairInt &l,const PairInt &r)
{
int lfirst = std::min(l.first,l.second);
int rfirst = std::min(r.first,r.second);
if (lfirst<rfirst) return true;
if (rfirst<lfirst) return false;
return std::max(l.first,l.second)<std::max(r.first,r.second);
}

int main()
{
typedef std::set<PairInt,Compare*> IntSet;
IntSet intSet(compare);
intSet.insert(PairInt(1,3));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(4,1));
for (IntSet::const_iterator i=intSet.begin(); i!=intSet.end(); ++i) {
std::cerr << i->first << "," << i->second << "\n";
}
}
```

```

Output:

``````1,3
1,4
```

```
+2

source

All Articles