0

I'm trying to create a map whose key and value are both structs (stE and stR), so I have something like this:

 struct stR{
  char* est;
  char* et;     
 };

struct stE{
      int num;
      char* form; 
      char* et; 
      map<stE,stR> s; 
}; 

But when I want to insert a new element:

stE e;
e.num=1;
e.form="a";
e.et="b";

stE f;
f.num=2;
f.form="c";
f.et="d";

stR r;
r.est="e";
r.et="";

e.s.insert(make_pair(f, r));

It gives me an error:

C:\Dev-Cpp\include\c++\3.4.2\bits\stl_function.h In member function `bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = stEstado]':

I can't find what's the problem. Could anyone help me? Thanks in advance.

LaFeeVerte
  • 17
  • 4
  • 1
    Possible duplicate of [stl maps with user defined objects](http://stackoverflow.com/questions/1102392/stl-maps-with-user-defined-objects) and others. – juanchopanza May 02 '12 at 12:36

2 Answers2

3

When using a map, you need to provide a less-than operator or give it a comparer since it orders the keys automatically.

bool stE::operator< (const stE &);
chris
  • 60,560
  • 13
  • 143
  • 205
  • 2
    You either need that, or you'll have to declare a comparator class and give that as third template argument to `map<...>` in the definition to `struct stE`. – FrankH. May 02 '12 at 12:43
3

You need to provide strict weak ordering comparison, which you can achieve by defining operator< for your stE or passing a comparator function of functor as a map template parameter. std::map looks something like this:

template<class Key, class T, class Compare = std::less<Key>, ... > class map;

By default, Compare is set to use T::operator<(const T&), but you can pass your own functor type which implements the logic. This is important if you cannot modify the actual class.

Bear in mind that the map needs to be able to insert default constructed stR objects, and your current structure has no default constructor, to the pointers will be initialized to random values. This could be an issue further along the line.

Also, your key struct has a map where it is it's own key type. This could cause recursion problems when you try to implement the less-than comparison:

struct stE{
  int num;
  char* form; 
  char* et; 
  map<stE,stR> s; // how do we use this in the comparison?
}; 
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • std::map doesn't require its value_type to be default constructible (in general). The `map s;` member is more of a problem, because stE is incomplete at this point, which is illegal (although not all implementations actually reject it). – ymett May 02 '12 at 13:01
  • @ymett if the map's operator[] is called for a key that doesn't exist in the map, then the value will be default constructed. As for the incomplete type, I have to check the standard. GCC seems to swallow that without complaints :-) – juanchopanza May 02 '12 at 13:03
  • So if you want to use operator[] value_type must be default constructible, otherwise not. Many implementations will actually accept incomplete types, but the standard says it's undefined. – ymett May 16 '12 at 09:20