Jerome Baldridge - 1 year ago 76
C++ Question

# What is this use of std::map doing?

Can anyone explain the output I am getting from this simple program using

`std::map`
. Note that I insert
`p`
into the map, but not
`q`
yet it says it found them both, but also says there is only 1 element in the map!

``````#include <map>
#include <iostream>

struct screenPoint {
float x = 0, y = 0;
screenPoint(float x_, float y_): x{x_}, y{y_}{}
};

bool operator<(const screenPoint& left, const screenPoint& right){
return left.x<right.x&&left.y<right.y;
}

std::map<screenPoint, float> positions;

int main(int argc, const char * argv[]) {

auto p = screenPoint(1,2);
auto q = screenPoint(2,1);
positions.emplace(p,3);

auto f = positions.find(p);
auto g = positions.find(q);

if (f == positions.end()){
std::cout << "f not found";
} else {
std::cout << "f found";
}

std::cout << std::endl;

if (g == positions.end()){
std::cout << "g not found";
} else {
std::cout << "g found";
}

std::cout << std::endl;

std::cout << "number elements: " << positions.size() << "\n";
return 0;
}
``````

Output:

``````f found
g found
number elements: 1
``````

Answer Source

In order to use a data type in an `std::map`, it must have a particular ordering called a strict weak ordering (https://en.wikipedia.org/wiki/Weak_ordering). This means that the inequality operator (`<`) obeys a very specific set of rules. The operator you specified however is not a weak ordering. In particular, given two `screenPoint`s, `a` and `b` constructed from (1,2) and (2,1) respectively, you will see that it is false both that `a < b` and that `b < a`. In a strict weak ordering, this would be required to imply that `a == b`, which is not true!

Because your inequality operator does not meet the requirement of a strict weak ordering, `map` ends up doing unexpected things. I recommend reading up more details on what this ordering is, and reading/thinking about why map requires it. In the short term, you can redefine your operator as follows:

``````bool operator<(const screenPoint& left, const screenPoint& right){
if left.x < right.x return true;
else return (left.y < right.y);
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download