Having a struct as a key for a map

So why does this not work? As an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct example
{
    int x; int y;
};

int main()
{
    example variable;
    variable.x = 1;
    variable.y = 2;
    map<example, int> something;
    something[variable] = 3;
   
   return 0;
}


And I get a very long error message from the compiler. I tried using an enum as the key as well and that worked just fine, but I guess that's just the same as having an integer as the key. But anyway, what's the problem with this? Is there any way to make it work?
The issue is that the allocator for map doesn't know how to handle your custom structure. You can always pass pointers to structures to the map, or define your own allocator.
Either the key_type of a map must be LessThanComparable
or a comparison predicate (the third template parameter) has to be provided.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <map>

struct example
{
    int x; int y;
};

// LessThanComparable
bool operator< ( example a, example b ) { return std::make_pair(a.x,a.y) < std::make_pair(b.x,b.y) ; }

int main()
{
    example variable = { 1, 2 };
    std::map< example, int > something;
    something[variable] = 3;
}
Ah, that makes a lot of sense. Of course, since there is no equality operator for struct, then naturally it wouldn't work for a map anyway.
> since there is no equality operator

Must be LessThanComparable; need not be EqualityComparable.
Key equivalence is tested with !( key_a < key_b ) && !( key_b < key_a )
The == operator is not used even if it is present.

std::map<> will use our comparison predicate - one that imposes a strict weak ordering - if we provide one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <map>

struct example
{
    int x; int y;
};

struct our_cmp
{
    bool operator() ( example a, example b ) const
    { return std::make_pair(a.x,a.y) > std::make_pair(b.x,b.y) ; }
};

int main()
{
    example variable = { 1, 2 };
    std::map< example, int, our_cmp > something;
    something[variable] = 3;
}
Topic archived. No new replies allowed.