在某些C ++程序中,我有两个类 - Abc 和 Xyz 。 Abc 类包含一个整数成员 Foo ,如下面的清单所示:
class Abc { public: int Foo; Abc(int f) { Foo = f; } }; class Xyz{};
我正在使用地图< Abc , Xyz >但表现极差。这就是为什么我想使用hash_map< Abc , Xyz > (Dev-Cpp扩展库)和一些棘手的哈希。让我们假设以下 AbcHash 一元函数对象将作为哈希生成器运行良好:
class AbcHash { public: size_t operator() (const Abc &a) { return a.Foo % 123; } };
为了与STL保持一致,我还实现了一个 AbcCmp 比较器:
class AbcCmp { public: bool operator() (const Abc &a1, const Abc &a2) { return (a1.Foo == a2.Foo); } };
当我想最后使用hash_map时,我测试了 Abc 和 Xyz 类。那是我的主要:
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 }
最后一行会导致一些奇怪的编译错误:
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
我完全不知道这里有什么不妥。如何解决?
答案 0 :(得分:4)
我的第一个方法是确定为什么地图的表现很差。地图实际上是非常好的全能表演者 - 在某些情况下,他们可能会表现优于哈希表。在不知道问题的情况下更换容器不是一个好主意。
然后我会破坏DevC ++。这个古董非常多,并且不再处于积极的发展状态 - 我对使用它附带的任何库特别怀疑。我将切换到Code::Blocks的夜间版本,GCC的Twilight Dragon版本,以及(如果我仍然需要哈希)TR1或Boost哈希表实现。
答案 1 :(得分:0)
要解释第一个错误,我需要看看你如何键入deff的hash_map。 (你确实键入了它,不是吗?)。
你得到第二个错误的原因是因为你的AbcHash和AbcCmp声明应该将它们的operator()函数声明为const:
size_t operator() (const Abc &a) const
bool operator() (const Abc &a1, const Abc &a2) const
但是,我必须同意Neil的观点,即使用积极开发的库会更加明智。