【问题标题】:Reading a value in associative array creates a new key读取关联数组中的值会创建一个新键
【发布时间】:2010-06-28 16:52:53
【问题描述】:

我有这样的代码。我用

pvalueholder 是多态的类,它可以容纳各种类型,字符串..等。 它也可以有一个未定义的类型。

typedef hash_map<pvalueholder,pvalueholder,pvaluehasher > hashtype;
hashtype h;
pvalueholder v;
v="c";
h[v]=5; // h has one element

pvalueholder v2=h[v]; // here h gets a new key/value how is that possible?
cout << (string) (h[v]) << endl; // here h gets another new key/value how is that possible?
int i =0;
for (hashtype::iterator h1=h.begin(); h1!=h.end();h1++)
{
  cout << "no: " << i++ << endl;
} // this prints three lines, it should print one...

这里有两个值是未定义的,第三个是预期的5。

 size_t pvaluehasher::operator() (const pvalueholder& p) const
  {
      cout << "hashvalue:" <<  p.value->hashvalue() << endl;
   return p.value->hashvalue();

  }

返回 这是打印的内容: 哈希值:84696444 哈希值:84696444 哈希值:84696444 返回:1 哈希值:84696444 返回:1 哈希值:84696444 返回:1 返回:1 哈希值:84696444

你有什么想法吗? 谢谢。

解决方案: 对于 Microsoft STL,函数 operator()(parameter1,parameter2) 需要不同。 对于 microsoft,它需要返回 parameter1 和 parameter2 之间的小于关系。 对于 gcc,它需要返回相等性。我返回平等。 键的比较功能不正确... 该函数返回 true 表示相等,而它必须返回小于 Microsoft STL 的情况。

【问题讨论】:

    标签: visual-c++ visual-studio-2008 stl


    【解决方案1】:

    我的猜测是您的哈希函数不正确 - 这意味着它会在给定相同键 "c" 的情况下产生不同的哈希值。

    显示pvalueholder 的声明和pvaluehasher 的完整代码。

    【讨论】:

    • 即使在读取关联数组时,不正确的哈希函数也会导致生成新键吗?
    • 我追踪了哈希函数,它似乎返回了相同的数字。
    • @Aftershock,“如果没有找到参数键值,则与数据类型的默认值一起插入”,见msdn.microsoft.com/en-US/library/h90ew76k%28v=VS.80%29.aspx
    【解决方案2】:

    几乎不可能对hash_map 发表评论,因为它从未被标准化,并且现有的实现并不完全一致。更糟糕的是,您的代码似乎并不正确或无法编译 - 有些地方与键关联的值似乎是一个 int,而其他地方则是一个字符串。

    使用std::tr1::unordered_map 并修复其余代码以编译并且看起来合理,如下所示:

    #include <unordered_map>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    typedef std::tr1::unordered_map<std::string, int> hashtype;
    
    std::ostream &operator<<(std::ostream &os, std::pair<std::string, int> const &d) { 
        return os << d.first << ": " << d.second;
    }
    
    int main() {
        hashtype h;
        std::string v = "c";
    
        h[v]=5; // h has one element
    
        int v2=h[v]; 
        cout << h[v] << endl;
        int i =0;
        for (hashtype::iterator h1=h.begin(); h1!=h.end();h1++)
        {
          cout << *h1 << endl;
        } // this prints three lines, it should print one...
    
        return 0;
    }
    

    我得到的输出是:

    5
    c: 5
    

    这似乎很合理——正如预期的那样,我们只插入了一项。

    【讨论】:

      【解决方案3】:

      解决方案:在 Microsoft STL 的情况下,函数 operator()(parameter1,parameter2) 需要不同。对于 microsoft,它需要返回 parameter1 和 parameter2 之间的小于关系。对于 gcc,它需要返回相等性。我返回平等。键的比较函数不正确...函数返回 true 表示相等,而返回小于 Microsoft STL 的情况。

      【讨论】:

        猜你喜欢
        • 2022-01-12
        • 1970-01-01
        • 1970-01-01
        • 2010-11-07
        • 1970-01-01
        • 2013-04-23
        • 2012-10-22
        • 2021-05-11
        • 1970-01-01
        相关资源
        最近更新 更多