Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::set with user defined type, how to ensure no duplicates

Tags:

c++

set

So I have an std::set which needs to keep specific ordering as well as not allowing duplicates of a user defined (by me) type. Now I can get the order to work correctly by overloading the '<' operator in my type. However, the set does not appropriately detect duplicates, and to be honest I'm not entirely sure how it does this internally. I have overloaded the '==' operator, but somehow im not sure this is what the set is actually using? So the question is how does the set determine duplicates when you add values? Here is the relevant code:

The user defined type:

//! An element used in the route calculation. struct RouteElem {     int shortestToHere; // Shortest distance from the start.     int heuristic;      // The heuristic estimate to the goal.     Coordinate position;     bool operator<( const RouteElem& other ) const     {         return (heuristic+shortestToHere) < (other.heuristic+other.shortestToHere);     }     bool operator==( const RouteElem& other ) const     {         return (position.x == other.position.x && position.y == other.position.y);     } }; 

So the elements are equivalent when their position is equivalent, and an element is less than another if its combined functional is less than that of the other. The sorting works, but the set will accept two elements of the same position.

like image 219
DeusAduro Avatar asked Jul 11 '09 22:07

DeusAduro


2 Answers

operator== is not used by std::set. Elements a and b are considered equal iff !(a < b) && !(b < a)

like image 74
Paul Avatar answered Sep 20 '22 18:09

Paul


std::set supports specifying a comparison function. The default is less which will use operator < to check equality. You can define a custom function to check equality and use that one instead:

std::set<RouteElem, mycomparefunction> myset;  

Note that it's not possible to separate the comparison function from sorting function. std::set is a binary tree and if an element in a binary tree is not bigger nor smaller than a specific element, it should be in the same place. It does something like this in the place finding algorithm:

if (a < b) {     // check the left subtree } else if (b < a) {     // check the right subtree } else {     // the element should be placed here. } 
like image 32
mmx Avatar answered Sep 19 '22 18:09

mmx