Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a struct in std::map?

Tags:

c++

stl

stdmap

I have a complex struct i want to put as a key of the std::map to make a list of all unique objects fast:

union somecomplexstruct {
     struct {
        more_structs val1, val2;
        even_more_structs val3, val4;
        lots_of_more_structs val5;
     };
     unsigned int DATA[3];
};

typedef map<somecomplexstruct, int, greater<somecomplexstruct> > somecomplexstructMap;

But it says error: error C2784: 'bool std::operator >(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Alloc> &' from 'const somecomplexstruct'

How do i make my struct work there?

Edit: Got it working, thanks to everyone! Heres the code:

inline bool operator>(const somecomplexstruct &v1, const somecomplexstruct &v2){
    if(v1.DATA[0] > v2.DATA[0]) return 1;
    if(v1.DATA[0] < v2.DATA[0]) return 0;
    if(v1.DATA[1] > v2.DATA[1]) return 1;
    if(v1.DATA[1] < v2.DATA[1]) return 0;
    return v1.DATA[2] > v2.DATA[2];
}
like image 534
Newbie Avatar asked Dec 09 '22 13:12

Newbie


2 Answers

std::greater<> invokes operator>() to do its work, so you need to overload that if you want to use std::greater<>.

It should look like this:

inline bool operator>(const somecomplexstruct& lhs, const somecomplexstruct& rhs)
{
  // implement your ordering here. 
}
like image 60
sbi Avatar answered Dec 26 '22 11:12

sbi


With your operator> function, consider what happens if you compare {1, 0, 0} and {0, 1, 0}. If you compare a > b, it returns true from the first comparison. If you compare b > a it returns true from the second comparison. So its fails the reflexive property for comparisons, scrambling the map. In order for map to work properly, you must define your operator> such that a > b == !(b > a) for all possible non-equal pairs of values that might be compared.

edit

The easiest/best way to ensure that your operator is properly reflexive is to ensure the for every test that might return true, you also have a test with the same condition and the operands swapped that returns false. So if you have

if(v1.DATA[1] > v2.DATA[1]) return 1;

in your function, you need

if(v2.DATA[1] > v1.DATA[1]) return 0;

or the equivalent somewhere.

like image 32
Chris Dodd Avatar answered Dec 26 '22 12:12

Chris Dodd