首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何实现与CString一起使用的std::unordered_map哈希函数?

如何实现与CString一起使用的std::unordered_map哈希函数?
EN

Stack Overflow用户
提问于 2016-02-15 11:37:05
回答 3查看 4.3K关注 0票数 6

我想声明:

代码语言:javascript
运行
复制
std::unordered_map<CString, CString> m_mapMyMap;

但是当我构建时,我发现一个错误,告诉我标准C++没有为CString提供哈希函数,而CString有(LPCSTR)操作符。

如何正确地为CString实现哈希函数?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-01-07 19:17:48

基于std::string的MS实现,我创建了以下方法,可用于std::unordered_setstd::unordered_map

代码语言:javascript
运行
复制
namespace std {
    template <>
    struct hash<CString>
    {   // hash functor for CString
        size_t operator()(const CString& _Keyval) const
        {   // hash _Keyval to size_t value by pseudorandomizing transform
            return (_Hash_seq((const unsigned char*)(LPCWSTR)_Keyval, _Keyval.GetLength() * sizeof(wchar_t)));
        }
    };

    template <>
    struct hash<CStringA>
    {   // hash functor for CStringA
        size_t operator()(const CStringA& _Keyval) const
        {   // hash _Keyval to size_t value by pseudorandomizing transform
            return (_Hash_seq((const unsigned char*)(LPCSTR)_Keyval, _Keyval.GetLength() * sizeof(char)));
        }
    };
}

或者更普通的:

代码语言:javascript
运行
复制
namespace std {
    template<typename BaseType, class StringTraits>
    struct hash<CStringT<BaseType, StringTraits>> : public unary_function<CStringT<BaseType, StringTraits>, size_t>
    {   // hash functor for CStringT<BaseType, StringTraits>
        typedef CStringT<BaseType, StringTraits> _Kty;

        size_t operator()(const _Kty& _Keyval) const
        {   // hash _Keyval to size_t value by pseudorandomizing transform
            return (_Hash_seq((const unsigned char*)(StringTraits::PCXSTR)_Keyval,
                _Keyval.GetLength() * sizeof(BaseType)));
        }
    };
}
票数 3
EN

Stack Overflow用户

发布于 2016-02-15 11:40:40

std::unordered_map使用不使用(LPCSTR)运算符的std::hash<>。

您需要重新定义散列函数:

代码语言:javascript
运行
复制
template<class T> class MyHash;

template<>
class MyHash<CString> {
public:
    size_t operator()(const CString &s) const
    {
        return std::hash<std::string>()( (LPCSTR)s );
    }
};

std::unordered_map<CString,CString,MyHash> m_mapMyMap;

但是,为了获得更好的性能,请使用std::string代替CString作为键。

票数 2
EN

Stack Overflow用户

发布于 2022-06-02 16:56:49

在尝试了图克斯先生的建议之后,我不得不说这已经行不通了。std::_HashSeq删除std::unary_function在C++17中也被去除。

最后,我找到了另一个解决方案,它结合了微软的哈希实现的建议来使用std::basic_string_view的hasher:

代码语言:javascript
运行
复制
namespace std
{
template<typename BaseType, class StringTraits>
struct hash<ATL::CStringT<BaseType, StringTraits>>
{
    size_t operator()(const ATL::CStringT<BaseType, StringTraits>& key) const noexcept
    {
        return hash<basic_string_view<BaseType>>()(
            basic_string_view<BaseType>(
                key.GetString(),
                key.GetLength()));
    }
};
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35408362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档