开发者

Reading a value in associative array creates a new key

开发者 https://www.devze.com 2023-01-04 20:05 出处:网络
I have code such as this. I use pvalueholder is class that is polymorphic , it can hold all sort of types, string..etc..

I have code such as this. I use

pvalueholder is class that is polymorphic , it can hold all sort of types, string..etc.. It also can have a type undefined.

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...

Two values are undefined here, the third one is 5 as expected.

 size_t pvaluehasher::operator() (const pvalueholder& p) const
  {
      cout << "hashvalue:" <<  p.value->hashva开发者_如何学运维lue() << endl;
   return p.value->hashvalue();

  }

returns Here is what is printed: hashvalue:84696444 hashvalue:84696444 hashvalue:84696444 returns:1 hashvalue:84696444 returns:1 hashvalue:84696444 returns:1 returns:1 hashvalue:84696444

Do you have any ideas what it may be? Thank you.

Solution: the function operator()(parameter1,parameter2) needs to be different in case of Microsoft STL. For microsoft, it needs to return less than relationship between parameter1 and parameter2. For gcc, it needs to return equality. I returned equality. The comparison function for the keys was not correct... The function returned true for equality while it has to return less than in case of Microsoft STL.


My guess would be that your hash function is incorrect - meaning it produces different hash values given the same key "c".

Show the declaration for pvalueholder and full code for pvaluehasher.


It's almost impossible to comment on hash_map, because it's never been standardized, and the existing implementations aren't entirely consistent. Worse, your code doesn't seem to be correct or compilable as it stands -- some places the value associated with the key seems to be an int, and other places a string.

Using std::tr1::unordered_map and fixing the rest of the code to compile and seem reasonable, like this:

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

The output I get is:

5
c: 5

This seems quite reasonable -- we've inserted only one item, as expected.


Solution: the function operator()(parameter1,parameter2) needs to be different in case of Microsoft STL. For microsoft, it needs to return less than relationship between parameter1 and parameter2. For gcc, it needs to return equality. I returned equality. The comparison function for the keys was not correct... The function returned true for equality while it has to return less than in case of Microsoft STL.

0

精彩评论

暂无评论...
验证码 换一张
取 消