您的位置:首页 > 其它

hash_map中string为key的解决方法

2012-12-13 14:43 211 查看
当hash_map中使用string为key时,需用户扩展命名空间,否则报错如下:

/usr/lib/gcc/x86_64-redhat-linux/3.4.5/../../../../include/c++/3.4.5/ext/hashtable.h:518: error: no match for call to `(const __gnu_cxx::hash<std::string>) (const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)'

表明编译器错误,修改方法有如下几个方案:

方案一:

自己写一个头文件,当使用string为key时,加入该头文件即可。指明了不同编译器下扩展形式。(必杀技)。文件如下:

#ifndef HASH_MAP_HPP

#define HASH_MAP_HPP

#ifdef HAVE_CONFIG_H

#include <config.h>

#endif

#include <string>

#if defined(_STLPORT_VERSION)

    #include <hash_map>

    #include <hash_set>

    using std::hash;

    using std::hash_map;

    using std::hash_set;

#else // not using STLPORT

    #ifdef __GNUC__

        #if __GNUC__ >= 3

            #include <ext/hash_map>

            #include <ext/hash_set>

            namespace __gnu_cxx {

                template <>

                struct hash<std::string> {

                    size_t operator()(const std::string& s) const {

                        unsigned long __h = 0;

                        for (unsigned i = 0;i < s.size();++i)

                            __h ^= (( __h << 5) + (__h >> 2) + s[i]);

                        return size_t(__h);

              

                    }

                    

                };

            }

            using __gnu_cxx::hash_map;

            using __gnu_cxx::hash;

        #else // GCC 2.x

            #include <hash_map>

            #include <hash_set>

            namespace std {

                struct hash<std::string> {

                    size_t operator()(const std::string& s) const {

                        unsigned long __h = 0;

                        for (unsigned i = 0;i < s.size();++i)

                            __h ^= (( __h << 5) + (__h >> 2) + s[i]);

                        return size_t(__h);

                    }

                };

            };

            using std::hash_map;

            using std::hash_set;

            using std::hash;

        #endif // end GCC >= 3

    #elif defined(_MSC_VER) && ((_MSC_VER >= 1300) || defined(__INTEL_COMPILER))

        // we only support MSVC7+ and Intel C++ 8.0

        #include <hash_map>

        #include <hash_set>

        namespace stdext {

            inline size_t hash_value(const std::string& s) {

                unsigned long __h = 0;

                for (unsigned i = 0;i < s.size();++i)

                    __h ^= (( __h << 5) + (__h >> 2) + s[i]);

                return size_t(__h);

            }

        }

        using std::hash_map; // _MSC_EXTENSIONS, though DEPRECATED

        using std::hash_set;

    #else

        #error unknown compiler

    #endif //GCC or MSVC7+

#endif // end STLPORT

#endif /* ifndef HASH_MAP_HPP */

方案二:

想简单一些,快速使用,可遵照如下写法:

#include <iostream>
#include <string>
#include <ext/hash_map>
using namespace std;
using namespace __gnu_cxx;

namespace __gnu_cxx

{

    template<> struct hash<const string>

    {

        size_t operator()(const string& s) const

        { return hash<const char*>()( s.c_str() ); } //

__stl_hash_string

    };

    template<> struct hash<string>

    {

        size_t operator()(const string& s) const

        { return hash<const char*>()( s.c_str() ); }

    };

}

int main( void )

{

    hash_map<string,int> test;

    test["abc"] = 1;

    cout << test["abc"] << endl;

    system( "pause" );

}
方案三:
再扩展一些,当使用long做key时,同样扩展:

#ifndef EXT_HASH_FUNCTION_HPP_INCLUDED
#define EXT_HASH_FUNCTION_HPP_INCLUDED

#ifdef __GNUC__
namespace __gnu_cxx
{
        template<>
        struct hash<long long>
        {
                size_t operator()(long long __x) const
                {
                        if (sizeof(__x) == sizeof(size_t))
                                return __x;
                        else
                                return (__x >> 32) ^ (__x & 0xFFFFFFFF);
                }
        };

        template<>
        struct hash<unsigned long long>
        {
                size_t operator()(unsigned long long __x) const
                {
                        if (sizeof(__x) == sizeof(size_t))
                                return __x;
                        else
                                return (__x >> 32) ^ (__x & 0xFFFFFFFF);
                }
        };

        template<typename Traits, typename Allocator>
        struct hash<std::basic_string<char, Traits, Allocator> >
        {
                size_t operator()(const std::basic_string<char, Traits, Allocator>& __s) const
                {
                        return __stl_hash_string(__s.c_str());
                }
        };

}
#endif

#endif//EXT_HASH_FUNCTION_HPP_INCLUDED
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: