Чтение значения в ассоциативном массиве создает новый ключ - PullRequest
1 голос
/ 28 июня 2010

У меня есть такой код. Я использую

pvalueholder - это полиморфный класс, он может содержать все виды типов, string..etc .. Он также может иметь тип 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...

Здесь два значения не определены, третье - 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

У вас есть идеи, что это может быть? Спасибо.

Решение: Оператор функции () (параметр1, параметр2) должен быть другим в случае Microsoft STL. Для Microsoft это должно вернуть меньше, чем отношение между параметром 1 и параметром 2. Для gcc необходимо вернуть равенство. Я вернул равенство. Функция сравнения для ключей была неправильной ... Функция вернула true для равенства, в то время как должна возвращать меньше, чем в случае Microsoft STL.

Ответы [ 3 ]

2 голосов
/ 28 июня 2010

Практически невозможно прокомментировать 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

Это кажется вполне разумным - мы вставили только один элемент, как и ожидалось.

2 голосов
/ 28 июня 2010

Я полагаю, что ваша хеш-функция неверна - это означает, что она выдает разные хеш-значения при одинаковом ключе "c".

Показать объявление для pvalueholder и полный код для pvaluehasher.

0 голосов
/ 07 июля 2010

Решение: функция оператора () (параметр1, параметр2) должна отличаться в случае Microsoft STL. Для Microsoft это должно вернуть меньше, чем отношение между параметром 1 и параметром 2. Для gcc необходимо вернуть равенство. Я вернул равенство. Функция сравнения для ключей была неправильной ... Функция вернула true для равенства, но должна возвращать меньше, чем в случае Microsoft STL.

...