Problem with std::map

Started by
8 comments, last by ToohrVyk 17 years, 1 month ago
I am using this map to link link a resource type to a list of lines to render. My problem is that no matter what I do I can only have a map size of 1 even though I have 3 different resources (right now it only has a vector3 for color). So I am pretty much only getting all my lines to render as red, when then should be rendering as red, green, and blue.

void RenderQueue::AddLine(const RenderResource& res, Vector3& pos1, Vector3& pos2)
{
ResourceLineQueue::iterator it = mQueue.find(res);

if ( it == mQueue.end() )
{
  std::vector<_line> vec; // dont think i need this but in here to be sure
  mQueue[res] = vec;
  it = mQueue.find(res);
}

if ( it->first != res)
{
//it almost always gets here
}

_line line;
line.pos1 = pos1;
line.pos2 = pos2;

it->second.push_back(line);

}


I hope you can spot my error, since I may just be overlooking it! There might be some typos here since my source code is not on this computer (the one its on has no internet at the moment :( ). Also I know this is kind of sloppy coding since it only supports one line, but I am planning to build from it once I get this 'simple' set up and working!
Advertisement
You should show us the comparison operators of RenderResource too, since its your key in the map.

And your map declaration.

thanks
Here is the render resource structure

typedef std::map< RenderResource, std::vector<_line> > RenderLineQueue;struct RenderResource{  Vector3 color;  inline operator < (const RenderResource& res)  {    if (color < res.color) return true;    return false;  }  inline operator == (const RenderResource& res)  {    return (color == res.color);  }}
What does operator< mean for a color? Is it lexicographic comparison? Did you implement it yourself? Is it correct?
Ok ill post the comparison for a vector3(which is the color variable)

inline bool operator< (const Vector3& vec)
{
if ( x < vec.x && y < vec.y && z < vec.z ) return true;
return false;
}
Under your vector comparison operator the vectors (0, 1, 2) and (0, 7, 9) are equivalent. What you want is:
// you should prefer non-member functions to member functions when possiblebool operator<(const Vector3 & lhs, const Vector3 & rhs){	return lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y) || (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z < rhs.z);}
Σnigma
Quote:
inline bool operator< (const Vector3& vec)
{
if ( x < vec.x && y < vec.y && z < vec.z ) return true;
return false;
}


This is definitely not a complete order relationship. For instance, (1,0,0) and (0,1,0) are uncomparable. And since you didn't provide a complete order, your map has undefined behaviour (which coincidentally results in treating uncomparable objects as if they were equal, but this is not guaranteed either AFAIK).

Better code would involve implementing lexicographic ordering, better known as:

inline bool operator< (const Vector3& a, const Vector3 & b){  if (a.x < b.x) return true;  if (a.x > b.x) return false;  if (a.y < b.y) return true;  if (a.y > b.y) return false;  if (a.z < b.z) return true;  return false;}


[Edited by - ToohrVyk on March 10, 2007 10:15:48 AM]
That comparison operator isn't really valid, as it doesn't define the necessary type of ordering over all Vector3 values. (It should be a strict-weak-ordering, if memory serves). Anyway, the problem is that you can have two Vector3 objects, like a = (0, 0, 1) and b = (1, 0, 0) where (a < b) is false, (b < a) is false, and (a != b). That's bad for your usage.

Instead, you should define the order lexicographically:

if (a.x < b.x) -> a < b
if (b.x < a.x) -> b < a

a.x and b.x are equal, move to y:
if (a.y < b.y) -> a < b
if (b.y < a.y) -> b < a

a.y and b.y are equal, move to z:
if (a.z < b.z) -> a < b
if (b.z < a.z) -> b < a

a and b are equal, return false (neither one is less than the other).
Thanks it works now!

I have a question regarding this new implimentation. When should I use the way I was using and the way that you showed me?
Quote:Original post by starfleetrp
I have a question regarding this new implimentation. When should I use the way I was using and the way that you showed me?


Off the top of my head, your implementation would only be useful in some precise stochastic computations, such as hedge portofolio construction, and some similar algorithms. It's useless for ordering the objects, since it isn't complete, and vector comparison does not have a general meaning in mathematics anyway.

This topic is closed to new replies.

Advertisement