4

Trying to brush up on my C++ and STL proficiency, running into a problem with std::map keyed by a structure I've defined. Relevant code:

typedef struct key_t {
   int a;
   int b;
   bool operator==(const key_t& rhs)
   {
      return (a == rhs.a) && (b == rhs.b);
   }
   bool operator<(const key_t& rhs) //added the when I saw this error, didn't help
   {
      return a < rhs.a;
   }
} key_t;

std::map<key_t, int> fooMap;

void func(void)
{
    key_t key;        
    key.a = 1;
    key.b = 2;

    fooMap.insert(std::pair<key_t, int>(key, 100));
}

Error looks like this:

"/opt/[redacted]/include/functional", line 133: error: no operator "<" matches these operands
            operand types are: const key_t < const key_t
          detected during:
            instantiation of "bool std::less<_Ty>::operator()(const _Ty &, const _Ty &) const [with _Ty=key_t]" at line 547 of "/opt/[redacted]/include/xtree"
instantiation of "std::_Tree<_Traits>::_Pairib std::_Tree<_Traits>::insert(const std::_Tree<_Traits>::value_type &) [with _Traits=std::_Tmap_traits<key_t, UI32, std::less<key_t>, std::allocator<std::pair<const key_t, UI32>>, false>]"

What am I doing wrong? Is it just flat-out awful/impossible to use structures as a map key? Or something else I'm overlooking?

4

2 に答える 2

5

This

 bool operator<(const key_t& rhs)

needs to be a const method

 bool operator<(const key_t& rhs) const

The two are different signatures, and std::less looks for the latter. The latter, as a const method, implying that it won't modify the object. The former however without const may imply that a modification to this may be performed.

In general its a good idea to have const methods, even if you can cast in away, it implies a promise to the client that no modifications will take place.

于 2012-11-20T19:00:55.243 に答える
1

For starters, the operators have to be const. (And you don't need the == operator.)

And where did you learn to use a typedef for a struct. There's no reason for it.

And finally, if you want both elements to participate as part of the key, you'll have to compare both of them:

struct Key
{
    int a;
    int b;
    bool operator<( Key const& rhs ) const
    {
        return a < rhs.a
            || ( !(rhs.a < a) && b < rhs.b );
    }
};

Otherwise, Key( 1, 2 ) and Key( 1, 3 ) will effectively be equal.

于 2012-11-20T19:02:36.443 に答える