2009-12-19 6 views
0

Dans certains programmes C++, j'ai deux classes - Abc et Xyz. La classe Abc contient un membre entier Foo, comme dans la liste suivante:Hash Problème d'objet en C++

 
class Abc 
{ 
public: 
int Foo; 
Abc(int f) 
{ 
    Foo = f; 
} 
}; 
class Xyz{}; 

J'utilise une carte < Abc, Xyz> mais la performance est extrêmement pauvre. C'est pourquoi je voudrais utiliser un hash_map < Abc, Xyz> (Bibliothèques d'extension Dev-Cpp) et quelques hachages difficiles. Supposons que les éléments suivants AbcHash objet fonction unaire va bien agir comme un générateur de hachage:

 
class AbcHash 
{ 
public: 
size_t operator() (const Abc &a) 
{ 
    return a.Foo % 123; 
} 
}; 

souci de cohérence avec STL j'ai également mis en place un comparateur AbcCmp:

 
class AbcCmp 
{ 
public: 
bool operator() (const Abc &a1, const Abc &a2) 
{ 
    return (a1.Foo == a2.Foo); 
} 
}; 

I J'avais testé les classes Abc et Xyz, quand je voulais enfin utiliser hash_map. C'est mon principal :

 
int main(int argc, char *argv[]) 
{ 
hash_map myMap; 

Abc a(10); 
a.Foo = 23; 

Xyz x(); 

myMap[a] = x; // this line fails the compilation 
} 

La dernière ligne provoque des erreurs de compilation étrange:

 
Compiler: Default compiler 
Building Makefile: "C:\user\hdr\hashfunc\Makefile.win" 
Executing make... 
make.exe -f "C:\user\hdr\hashfunc\Makefile.win" all 
g++.exe -c main.cpp -o main.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" 

In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/hash_map.h:59, 
       from main.cpp:2: 
C:/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the header for the header for C++ includes, or instead of the deprecated header . To disable this warning use -Wno-deprecated. 
main.cpp: In function `int main(int, char**)': 
main.cpp:45: error: no match for 'operator=' in '(&myMap)->__gnu_cxx::hash_map::operator[] [with _Key = Abc, _Tp = Xyz, _HashFcn = AbcHash, _EqualKey = AbcCmp, _Alloc = std::allocator](((const Abc&)((const Abc*)(&a)))) = x' 
main.cpp:14: note: candidates are: Xyz& Xyz::operator=(const Xyz&) 

C:/Dev-Cpp/include/c++/3.4.2/ext/hashtable.h: In member function `size_t __gnu_cxx::hashtable::_M_bkt_num_key(const _Key&, size_t) const [with _Val = std::pair, _Key = Abc, _HashFcn = AbcHash, _ExtractKey = std::_Select1st >, _EqualKey = AbcCmp, _Alloc = std::allocator]': 
C:/Dev-Cpp/include/c++/3.4.2/ext/hashtable.h:523: instantiated from `size_t __gnu_cxx::hashtable::_M_bkt_num(const _Val&, size_t) const [with _Val = std::pair, _Key = Abc, _HashFcn = AbcHash, _ExtractKey = std::_Select1st >, _EqualKey = AbcCmp, _Alloc = std::allocator]' 
C:/Dev-Cpp/include/c++/3.4.2/ext/hashtable.h:887: instantiated from `void __gnu_cxx::hashtable::resize(size_t) [with _Val = std::pair, _Key = Abc, _HashFcn = AbcHash, _ExtractKey = std::_Select1st >, _EqualKey = AbcCmp, _Alloc = std::allocator]' 
C:/Dev-Cpp/include/c++/3.4.2/ext/hashtable.h:701: instantiated from `typename __gnu_cxx::hashtable::reference __gnu_cxx::hashtable::find_or_insert(const _Val&) [with _Val = std::pair, _Key = Abc, _HashFcn = AbcHash, _ExtractKey = std::_Select1st >, _EqualKey = AbcCmp, _Alloc = std::allocator]' 
C:/Dev-Cpp/include/c++/3.4.2/ext/hash_map:181: instantiated from `_Tp& __gnu_cxx::hash_map::operator[](const typename __gnu_cxx::hashtable, _Key, _HashFcn, std::_Select1st >, _EqualKey, _Alloc>::key_type&) [with _Key = Abc, _Tp = Xyz, _HashFcn = AbcHash, _EqualKey = AbcCmp, _Alloc = std::allocator]' 
main.cpp:45: instantiated from here 
C:/Dev-Cpp/include/c++/3.4.2/ext/hashtable.h:518: error: passing `const AbcHash' as `this' argument of `size_t AbcHash::operator()(const Abc&)' discards qualifiers 

make.exe: *** [main.o] Error 1 

Execution terminated 

Je n'ai complètement aucune idée de ce qui peut se tromper ici. Comment peut-il être réparé?

+0

Veuillez poster votre code actuel; votre déclaration de votre hash_map n'inclut pas les paramètres modélisés, par exemple. En outre, vous devriez utiliser unordered_map de tr1 au lieu de hash_map. Enfin, vous déclarez (10) puis réattribuez foo juste après. Pourquoi ne pas déclarer un Abc a (23) en une seule étape? – Joe

+0

Est-ce que votre classe Abc met en œuvre l'opérateur less than? Si ce n'était pas le cas, cela pourrait être la raison des problèmes de performance que vous avez vus. –

Répondre

4

Ma première approche serait d'identifier pourquoi la performance de la carte est pauvre. Les cartes sont en fait assez performantes dans tous les domaines - elles peuvent surclasser les tables de hachage dans certaines circonstances. Changer de conteneurs sans connaître le problème n'est pas une bonne idée.

Ensuite, je voudrais indésirable DevC++. Cette antiquité est extrêmement buggée et n'est plus en développement actif - je serais particulièrement douteuse à propos de l'utilisation des bibliothèques qui l'accompagnent. Je passerais à une version nocturne de Code::Blocks, la version Twilight Dragon de GCC, et (si je voulais toujours un hachage) aux implémentations de hachage TR1 ou Boost.

+0

Je seconde la recommandation Code :: Blocks! –

0

Pour expliquer la première erreur, je voudrais voir comment vous typedef'd hash_map. (Vous avez fait typedef, n'est-ce pas?).

La raison pour laquelle vous obtenez la deuxième erreur est parce que vos déclarations de AbcHash et AbcCmp doivent déclarer leur opérateur() fonctionne comme const:

size_t operator() (const Abc &a) const 

bool operator() (const Abc &a1, const Abc &a2) const 

Cependant, je suis d'accord avec Neil que l'utilisation d'un développement actif bibliothèque serait beaucoup plus sage.