hash_map中string为key的解决方法

32 篇文章 0 订阅

http://www.2cto.com/kf/201212/175865.html?fw_key=B1F0185619DE4962

当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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您的问题是关于如何使用 RedisTemplate 将一个包含字段 unitCode、unitName 和 zbu 列表的 OrgUnitProDto 对象转换为 Map<String, Map<String, String>> 并存储在 Redis 。具体地,您想知道如何使用 RedisTemplate 的 opsForHash() 方法将转换后的 Map<String, Map<String, String>> 对象存储在 key 为 ORG_EMP_MAP_KEY 的 Redis hash ,其 unitCode 作为 cacheMapkey,unitName 和 zbu 组成的 Map<String, String> 对象作为 cacheMap 的 value 是吗? 如果是的话,您可以按照以下步骤操作: 1. 首先,确保您已经将 RedisTemplate 注入到了当前的 Spring 容器。 2. 接下来,您可以使用 opsForHash() 方法获取一个 HashOperations 对象,用于操作 Redis 的 hash 类型数据。 ```java HashOperations<String, String, Map<String, String>> hashOps = redisTemplate.opsForHash(); ``` 在这里,String 表示 Redis 的 key 的类型,String 表示 Redis 的 hash key 的类型,Map<String, String> 表示 Redis 的 hash value 的类型。请根据您的实际情况进行调整。 3. 然后,您可以将 OrgUnitProDto 对象转换成一个 Map<String, Map<String, String>> 对象,其 unitCode 作为外层的 key,unitName 和 zbu 组成的 Map<String, String> 对象作为内层的 value。 ```java Map<String, Map<String, String>> cacheMap = new HashMap<>(); Map<String, String> unitMap = new HashMap<>(); unitMap.put("unitName", orgUnitProDto.getUnitName()); unitMap.put("zbu", orgUnitProDto.getZbu()); cacheMap.put(orgUnitProDto.getUnitCode(), unitMap); ``` 4. 最后,您可以使用 hashOps.put() 方法将转换后的 Map<String, Map<String, String>> 对象存储到 Redis 。 ```java hashOps.put("ORG_EMP_MAP_KEY", cacheMap); ``` 在这里,第一个参数表示 Redis 的 key,第二个参数表示要存储的数据。请根据您的实际情况进行调整。 这样,您就可以将一个包含字段 unitCode、unitName 和 zbu 列表的 OrgUnitProDto 对象转换为 Map<String, Map<String, String>> 并存储在 Redis 了。希望能对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值