Usando struct como CLAVE y VALOR para el mapa. operación find () dando error

Code in c++:

#include <iostream>
#include <map>
#include <string>

using namespace std;

struct keyInfo
{
  string Key1; 
  string Key2; 

  bool keyInfo::operator <(keyInfo &A) const
    { return ((this->Key1<A.Key1)&&(this->Key2<A.Key2)); }
};

struct valueInfo
{ 
  int value1; 
  int value2; 
  int value3; 

  valueInfo(const int A,const int B,const int C) : 
    value1(A),value2(B),value3(C) {}
};
typedef std::map<keyInfo, valueInfo> MapTYPE;

int main()
{
  MapTYPE TMap;
  keyInfo K;
  K.Key1="main";
  K.Key2="i";
  valueInfo V(-2,-3322,9000);

  TMap.insert(MapTYPE::value_type(K,V));
  MapTYPE::iterator It1=TMap.find(K);
  It1=TMap.find(K);
  if(It1!=TMap.end())
    std::cout<<"Success(K): "<<It1->second.value2<<std::endl;

  keyInfo E;
  E.Key1="main";
  E.Key2="j";
  //TMap.insert(std::pair<keyInfo,valueInfo>(E,V));
  MapTYPE::iterator It2=TMap.find(E);
  if (It2!=TMap.end())
     std::cout<<"Success(E): "<<(It2->second).value3<<std::endl;

  cin.get();
  return 0;
 }

When I compile this code it gave me the error:

error C2679: binary '<' : no operator found which takes a right-hand operand of type 'const keyInfo1' (or there is no acceptable conversion)

Please let me know where I'm going wrong? Any help is highly appreciated. Thanks.

I have tried to implement own operator and used in map<>, code looks as follows:

#include <iostream>
#include <map>
#include <string>

using namespace std;

struct keyInfo
{
  string Key1; 
  string Key2; 

  /*bool keyInfo::operator()(keyInfo const& Left,keyInfo const& Right) const{
      return ((Left.Key1<Right.Key1)&&(Left.Key2<Right.Key2));
  }*/
};

struct LessComparer{
    bool operator()(keyInfo const& Left,keyInfo const& Right) const{
        return !(Left.Key1==Right.Key1 && Left.Key2==Right.Key2);
    }
};

struct valueInfo
{ 
  int value1; 
  int value2; 
  int value3; 

  valueInfo(const int A,const int B,const int C) : 
    value1(A),value2(B),value3(C) {}
};
typedef std::map<keyInfo, valueInfo, LessComparer> MapTYPE;

int main()
{
  MapTYPE TMap;
  keyInfo K;
  K.Key1="main";
  K.Key2="i";
  valueInfo V(-2,-3322,9000);

  TMap.insert(MapTYPE::value_type(K,V));
  MapTYPE::iterator It1=TMap.find(K);
  It1=TMap.find(K);
  if(It1!=TMap.end())
    std::cout<<"Success(K): "<<It1->second.value2<<std::endl;

  keyInfo E;
  E.Key1="main";
  E.Key2="j";
  //TMap.insert(std::pair<keyInfo,valueInfo>(E,V));
  MapTYPE::iterator It2=TMap.find(E);
  if (It2!=TMap.end())
     std::cout<<"Success(E): "<<(It2->second).value3<<std::endl;

  cin.get();
  return 0;
 }

Here I'm using operator() to return 0 iff both Key1 and Key2 of Left and Right are equal. I think this is the same way map::less works, I mean it return false only if equality condition is satisfied.

It works fine in first case i.e. TMap.find(K) where same key is found. But during call in second case i.e. TMap.find(E) it pops up an error saying:

"Debug assertion failed"
Expression: Invalid operator <

preguntado el 10 de marzo de 12 a las 14:03

In addition to making the parameter const, you should also consider if you realmente want to have both keys less than each other. What happens if Key1 es igual a A.Key1? -

2 Respuestas

Tu declaración de operator< esta apagado.

struct keyInfo
{
  string Key1; 
  string Key2; 

  bool keyInfo::operator <(keyInfo &A) const
    { return ((this->Key1<A.Key1)&&(this->Key2<A.Key2)); }
};

... and for several reasons:

  1. It is an error to prefix the declaration with the class name within the class. You only should do so if you define it outside the class. Some compilers are laxist, but the Standard says you should not do this.
  2. The reason you cannot compile is that operator< should accept both its operands either as values (for simple things) or by const&. Here you forgot the const para A.
  3. The definition is incorrect, your operator< has its semantics off as the properties of antisymmetry is not respected.
  4. It is recommended that binary operators be declared as free functions outside the class.

All in all, the correct declaration and definition are:

struct keyInfo {
  std::string Key1;
  std::string Key2;
};

inline bool operator<(keyInfo const& left, keyInfo const& right) {
  if (left.Key1 < right.Key1) { return true; }
  if (left.Key1 > right.Key1) { return false; }
  return left.Key2 < right.Key2;
}

If you can use Boost, a "simple" way to implement this is:

inline bool operator<(keyInfo const& left, keyInfo const& right) {
  return boost::tie(boost::cref(left.Key1) , boost::cref(left.Key2))
       < boost::tie(boost::cref(right.Key1), boost::cref(right.Key2));
}

respondido 10 mar '12, 14:03

@EthanSteinberg: thanks, but I don't remember off the top of my head if the boost:cref call is necessary. I think you can get away without it with tie... but just didn't want to take any chance here. - Matthieu M.

I have tried using own comparer. can you reply to link: Using Own Comparator - ND Thokare

Change parameter to const keyInfo& A:

bool keyInfo::operator <(const keyInfo &A) const  // keyInfo:: is unrequired here

In std::map the key is held as const T así que cuando el std::map implementation invokes keyInfo.operator<() it is passing a const keyInfo&, que no se puede convertir en un keyInfo&.

respondido 10 mar '12, 14:03

I have changed parameter to const keyInfo& A , still the same occurs. - ND Thokare

I have tried using own comparer. can you reply to link: Using Own Comparator - ND Thokare

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.