zoukankan      html  css  js  c++  java
  • GCC hash_map中string为key的解决方法[Linux]

    原文:http://blog.csdn.net/langlang2671/article/details/8290678


    当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


  • 相关阅读:
    多线程编程(8)Timer
    WPF 元素的查找
    拖放操作和文件复制小功能
    gridview 编辑,删除,更新的用法
    VS2005 制作安装程序
    C# 学习基础概念二十五问
    DBHelper
    c# 实现网页上用户自动登陆|asp.net 模拟网站登录
    C#模拟登录总结
    Python 调用.net framework写的类库的方法
  • 原文地址:https://www.cnblogs.com/black/p/5171599.html
Copyright © 2011-2022 走看看