Make an std::map with a coordinate as key
c++, stdmap, visual-c++
Solution
« std::map is a sorted associative container that contains key-value pairs with unique keys. Keys are sorted by using the comparison function Compare. » from cppreference
The default comparison function is `std::less` which will use the operator< on the `Key` objects.
Thus, the problem lies in the `operator<` of `Coordinate` :
bool operator<(const Coordinate& coord) const {
if(x + y + z < coord.x + coord.y + coord.z)
return true;
return false;
}
`(1, 0, 0) < (0, 1, 0)` is false but `(0, 1, 0) < (1, 0, 0)` is also false, so as far as `std::map` is concerned, `(1, 0, 0) == (0, 1, 0)`.
In order to use `Coordinate` objects as keys in a `std::map`, you'll need to find the correct strict weak ordering criterion (the `operator<`) that meets your needs.
As other said, you could use something like `std::tie` (in C++11) which will first compare `x`, then `y` then `z` like this :
bool operator<(const Coordinate& coord) const {
if(x < coord.x) return true;
if(x > coord.x) return false;
//x == coord.x
if(y < coord.y) return true;
if(y > coord.y) return false;
//x == coord.x && y == coord.y
if(z < coord.z) return true;
if(z > coord.z) return false;
//*this == coord
return false;
}
Problem
It seems impossible to create an std::map with a coordinate as key. When (x+y+z) is the same for both coordinates, the map just overrides the previous one. Example: ``` map[Coordinate(1, 0, 0)] = object1; map[Coordinate(0, 1, 0)] = object2; map[Coordinate(0, 0, 1)] = object3; ``` This will result in there being a std::map with 1 element, which contains `object3` as value and `Coordinate(0, 0, 1)` as key. How can I prevent this so it'll contain all values? ``` #pragma once struct Coordinate { double x, y, z; Coordinate(double x, double y, double z) : x(x), y(y), z(z) {} bool operator<(const Coordinate& coord) const { if(x + y + z < coord.x + coord.y + coord.z) return true; return false; } bool operator==(const Coordinate& coord) const { if(x == coord.x && y == coord.y && z == coord.z) return true; return false; } inline bool isInRange(Coordinate coord, int range) const { if(pow(coord.x - this->x, 2) + pow(coord.y - this->y, 2) + pow(coord.z - this->z, 2) <= range*range) return true; return false; } }; ```