Jump to content
  • Advertisement
Sign in to follow this  
Mizipzor

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by godecho
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.

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 this post


Link to post
Share on other sites
Quote:
Original post by godecho
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.


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 this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
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.


Ah, good to know.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!