使用struct作为KEY和VALUE for map。 find()操作给出错误

时间:2012-03-10 14:13:58

标签: c++ map struct operator-overloading

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;
 }

当我编译这段代码时,它给了我错误:

  

错误C2679:二进制'&lt;' :找不到哪个运算符采用'const keyInfo1'类型的右手操作数(或者没有可接受的转换)

请让我知道我哪里出错了? 任何帮助都非常感谢。 感谢。

我试图实现自己的运算符并在map&lt;&gt;中使用,代码如下:

#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;
 }

这里我使用operator()返回0,如果左和右的Key1和Key2都相等。我认为这与map :: less的工作原理相同,我的意思是只有满足相等条件才会返回false。

在第一种情况下工作正常,即TMap.find(K),其中找到相同的密钥。但在第二种情况下的调用期间,即TMap.find(E),它会弹出错误说:

"Debug assertion failed"
Expression: Invalid operator <

2 个答案:

答案 0 :(得分:6)

您的operator<声明已关闭。

struct keyInfo
{
  string Key1; 
  string Key2; 

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

......有几个原因:

  1. 使用类中的类名称为声明添加前缀是错误的。如果你在课外定义它,你应该这样做。有些编译器是松散的,但标准说你不应该这样做。
  2. 无法编译的原因是operator<应该接受其操作数作为值(对于简单的事物)或const&。在这里,您忘记了const的{​​{1}}。
  3. 定义不正确,A的语义已关闭,因为operator<的属性未得到尊重。
  4. 建议将二元运算符声明为类外的自由函数。
  5. 总而言之,正确的声明和定义是:

    antisymmetry

    如果你可以使用Boost,实现这个的“简单”方法是:

    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;
    }
    

答案 1 :(得分:1)

将参数更改为const keyInfo& A

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

std::map中,密钥保留为const T,因此当std::map实施调用keyInfo.operator<()时,它会传递const keyInfo&,但无法将其转换为keyInfo&