# Invalid operator in std::map

This topic is 3785 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Im using hgeVector in a std::map as the key. My Tile class is the value.
/** needed for sorting by vector in map */
const bool operator<( const hgeVector& a, const hgeVector& b )
{
if ( a.x < b.x && a.y < b.y ) return true;
if ( a.x > b.x && a.y > b.y ) return false;
return ( a.x < b.x || a.y < b.y );
}

typedef std::map<hgeVector, Tile*> TileMap;


The problem arises when doing std::map[ position ] = new Tile( id );, the map asserts and gives the error "invalid operator<". However, the first time I insert something into the map it works, but the second time, I get the assert. The first key I insert is (6,-3), which works, but the second one, (7,-4), asserts. The plan with the operator is simple; if both x and y is less, a is less. Else, if neither is less, a is not less. Then the special case; if x or y has the same value, a is less if either is less. Where is my misstake?

##### Share on other sites
I think this is because your operator< is faulty. For example, (6, -3) < (7, -4) and (7, -4) < (6, -3) both return true, but obviously that doesn't make sense.

You should reconsider what less-than means for vectors. Probably the best option would be a sort of lexicographic compare:

const bool operator<( const hgeVector& a, const hgeVector& b ){    return (a.x < b.x) || ( (a.x == b.x) && (a.y < b.y) );}

##### Share on other sites

I havent got the raw brainpower to be able to trace through the logic - but this is the way I structure comparators which I find is fairly readble. we just test each dimension and whether we need another dimension to help resolve otherwise returning false.

const bool operator<( const hgeVector& a, const hgeVector& b )
{
if ( a.x != b.x) return a.x < b.x; // first dim
if ( a.y != b.y) return a.y < b.y; // second dim
return false; // false in case of equality
}

##### Share on other sites
Quote:
 Original post by Gage64For example, (6, -3) < (7, -4) and (7, -4) < (6, -3) both return true, but obviously that doesn't make sense.

Very true indeed, I wonder how I couldnt spot that. :p

Anyways, both your snippets work, thanks and ++rating to you both! :)

##### Share on other sites
I'm just making a guess about the data types your vector holds, but remember there's something to keep in mind when performing equality tests on floats. Both of the solutions suggested here perform equality tests. They might be fine for your situation, but it's something that should be considered.

##### Share on other sites
Quote:
 Original post by godechoI'm just making a guess about the data types your vector holds, but remember there's something to keep in mind when performing equality tests on floats. Both of the solutions suggested here perform equality tests. They might be fine for your situation, but it's something that should be considered.

Actually, it isn't... or, at least, it doesn't turn out to matter. For all the vagaries of floating point math, trichotomy still holds true for real numbers in IEEE-754, and that's all that's needed here. Of course, the resultant ordering isn't going to be particularly coherent, but that's to be expected from any ℜ2→ℜ mapping.

##### Share on other sites
Quote:
 Original post by godechoI'm just making a guess about the data types your vector holds, but remember there's something to keep in mind when performing equality tests on floats. Both of the solutions suggested here perform equality tests. They might be fine for your situation, but it's something that should be considered.

Also mixing and matching == and < should probably not be considered good style given the distinction made in stl between the seperate concepts of equality and equivalence - sorry i cant find a good link but scott meyers covers it in effective stl. However for a practical use case that is not generic and confined to floats types i dont think its an issue.

##### Share on other sites
Quote:
 Original post by SneftelActually, it isn't... or, at least, it doesn't turn out to matter. For all the vagaries of floating point math, trichotomy still holds true for real numbers in IEEE-754, and that's all that's needed here. Of course, the resultant ordering isn't going to be particularly coherent, but that's to be expected from any ℜ2→ℜ mapping.

Ah, good to know.

1. 1
Rutin
46
2. 2
3. 3
4. 4
5. 5

• 12
• 10
• 12
• 10
• 13
• ### Forum Statistics

• Total Topics
632991
• Total Posts
3009748
• ### Who's Online (See full list)

There are no registered users currently online

×