0

I have the following compiler error, how could I fix it?

error:  instantiated from `_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = ar, _Tp = int, _Compare = std::less<ar>, _Alloc = std::allocator<std::pair<const ar, int> >]' 

This is the code:

#include <map>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstdlib>

using namespace std; 

class ar { 
  public:
  int a;
  int b;
  int c;
public:
  ar() : a(0), b(0), c(0) {}
};

int main() {
   map<ar, int> mapa;
   ar k;
   k.a = 6;
   k.b = 1;
   k.c = 0;
   mapa[k] = 1;

   //system("pause");
   return 0;
 }
Marius Bancila
  • 16,053
  • 9
  • 49
  • 91
  • First step toward fixing your programming errors: use reasonable indentation and variable names. –  Feb 19 '13 at 21:32
  • Relevant: http://stackoverflow.com/questions/6573225/what-requirements-must-stdmap-key-classes-meet-to-be-valid-keys – ryanbwork Feb 19 '13 at 21:35

3 Answers3

1

You need a comparison function for the map. You can either create operator< that compares two instances of ar, or you can create a custom function and pass it as the 3rd template parameter.

An example of the former might be:

class ar {
  ...
  bool operator<(const ar& rhs) const {
    return std::tie(a,b,c) < std::tie(rhs.a, rhs.b, rhs.c);
  }
  ...
};
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • why is it important to have comparison function in this case? my only wish in this case is that my class represent an index for map. – user2085124 Feb 19 '13 at 21:35
  • @user2085124 because the map orders it's elements in it's underlying container, and if it doesn't know **how** to order them, it can't do it. It relies on some Comparison function being present in it's `Key` type. – Tony The Lion Feb 19 '13 at 21:36
  • i am still getting the same error. could it be another problem? – user2085124 Feb 19 '13 at 21:42
  • @user2085124 - There was an error in my code, which I have fixed in my answer. Notice the change in function signature to `const`. Now it [works for me](http://ideone.com/0lfuqZ). – Robᵩ Feb 19 '13 at 21:51
  • why is it has to be const? – user2085124 Feb 19 '13 at 21:52
  • @user2085124 because comparing two keys should not change either of them. Otherwise the map could get seriously messed up. – juanchopanza Feb 19 '13 at 22:01
1

For a std::map you need to have overloaded operator< on the Key type of the map, because that is how the map will insert elements into it's underlying container.

class ar { 
  public:
  int a;
  int b;
  int c;
  public:
  ar() : a(0), b(0), c(0) {}
  bool operator<(const ar& other) const;
  };

bool ar::operator< (const ar& other) const // note the function has to be const!!!
{
   return (other.a < a) && (other.b < b) && (other.c < c); // or some such ordering
}

When overloading operator<, it's a good idea to in a similar fashion also overload operator>.

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
0

operator < must be available for the key type, or you should provide a comparison functor to the map constructor.

Marius Bancila
  • 16,053
  • 9
  • 49
  • 91