简体   繁体   English

插入C ++ Map STL容器失败

[英]insertions into c++ map STL container is failing

Please see the following code to understand my question better. 请参阅以下代码,以更好地理解我的问题。

class compareByValue {                                                                             
  public:                                                                                          
    bool operator()(const string* s1, const string* s2) const                                      
    {                                                                                              
      if (s1 == s2)                                                                                
        return true;                                                                               
      if ((s1==NULL) || (s2==NULL))                                                                
        return false;                                                                              
      return (0 == s1->compare(s2->c_str()));                                                      
    }                                                                                                                                                                                             
}; 

map<string*, string*, compareByValue> nodeIdToIpAddress;

for (int i = 0; i < nrec; ++i) {
  nodeIdToIpAddress[ptr1[i]] = ptr2[i];                                              
  cout << "Added " << *(ptr1[i]) << " , " << *(ptr2[i]) << endl;
}

cout << "map has " << nodeIdToIpAddress.size() << " elements!" << endl;

I have a map that maintains key,value pairs which are pointers to string objects. 我有一个维护键,值对(它们是指向字符串对象的指针)的映射。 I'm sure that neither keys nor values are NULL pointers. 我确定键和值都不是NULL指针。 When I run the above program (well, I skipped surrounding code to make it easier to understand), "Added ... ..." gets printed 49 times. 当我运行上述程序时(为了使内容更容易理解,我跳过了周围的代码),“ Added ...”被打印49次。 ptr1[i], ptr2[i] are pointers to string objects and are not NULL pointers because my program doesn't segfault. ptr1 [i],ptr2 [i]是指向字符串对象的指针,并且不是NULL指针,因为我的程序没有segfault。

The problem I have is, when I print size of map at the end, it says map has only 1 element in it. 我的问题是,当我在最后打印地图的大小时,它说地图中只有1个元素。

I would appreciate if someone can give me directions to find the fix. 如果有人可以给我指示以找到解决办法,我将不胜感激。 Thanks in advance. 提前致谢。

EDIT: @Mark solution worked like charm for me. 编辑:@Mark解决方案对我来说就像是魅​​力。 thanks 谢谢

EDIT2: After seeing valuable feedback from @Mark and @James, I think I don't need to store pointers to strings in my map. EDIT2:在看到@Mark和@James的宝贵反馈后,我认为我不需要在地图中存储指向字符串的指针。 I'm going to change my code to store strings as key/values which means I don't need custom comparator functor. 我将更改代码以将字符串存储为键/值,这意味着我不需要自定义比较器函子。 Thanks a lot. 非常感谢。

Your comparator is wrong: if (s1 == s2) must return false and the comparator must produce a strict weak ordering . 您的比较器是错误的: if (s1 == s2) 必须返回false ,并且比较器必须产生严格的弱阶

[For what it's worth, using a pointer type as the key for a std::map is unusual at best.] [就其价值而言,使用指针类型作为std::map的键最多是不寻常的。]

Your comparison operator isn't right. 您的比较运算符不正确。 As long as you can assume that no nulls are added, you can throw if you detect any: 只要可以假设未添加任何空值,就可以在检测到任何空值时抛出:

bool operator()(const string* s1, const string* s2) const                                      
{                                                                                              
  if (!s1 || !s2) throw std::runtime_error("Whatever");

  return *s1 < *s2;
}                                                                                 

EDIT: I should have elaborated on the reasoning here a bit more. 编辑:我应该在这里详细阐述其原因。 The comparison operation that you pass into a std::map (or set or sort for example) must satisfy strict weak ordering. 传递给std::map (或例如setsort )的比较操作必须满足严格的弱排序。 This basically means that x OP x is false , if x OP y is true then y OP x is false , and that x OP y , y OP z implies x OP z (as well as other rules regarding items that can't be compared). 这基本上意味着x OP xfalse ,如果x OP ytruey OP xfalse ,并且x OP yy OP z表示x OP z (以及其他无法比较的规则) )。

Your function didn't satisfy this in several ways: if (s1 == s2) needs to return false. 您的函数不能通过几种方式满足此要求: if (s1 == s2)需要返回false。 if ((s1==NULL) || (s2==NULL)) can't return false because it would imply that null < anything and anything < null . if ((s1==NULL) || (s2==NULL))不能返回false,因为这意味着null < anythinganything < null You'd have to split it up and return true for s1 null and false for s2 null. 您必须将其拆分并为s1 null返回true,为s2 null返回false。 return (0 == s1->compare(s2->c_str())); is incorrect because it's a three-way result rather than a < relation. 是不正确的,因为它是三向结果,而不是<关系。

Since you specified that nulls would never be inserted, the simplest resolution seemed to be to throw an exception in that case (if either was null) and thenuse the string built-in operator. 由于您指定了绝不插入空值,因此最简单的解决方案似乎是在这种情况下引发异常(如果其中一个为空),然后使用字符串内置运算符。

All that being said now, I would strongly consider NOT storing strings by pointer in containers unless you have actual evidence that it's a performance bottleneck. 现在,我将坚决考虑不要通过指针将字符串存储在容器中,除非您有确凿的证据表明这是性能瓶颈。 A simpler design is easier to maintain and keep correct, which tends to lead to better programs long-term. 更简单的设计更易于维护和保持正确性,这往往会导致长期更好的程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM