如何使用stdext :: hash_map,其中键是自定义对象?

Ben*_*n L 6 c++ stl hashmap

使用STL C++ hash_map ...

class MyKeyObject
{
    std::string str1;
    std::string str2;

    bool operator==(...) { this.str1 == that.str1 ... }
};

class MyData
{
    std::string data1;
    int data2;
    std::string etcetc;
};
Run Code Online (Sandbox Code Playgroud)

像这样...

MyKeyObject a = MyKeyObject(...);
MyData b = MyData(...);

stdext::hash_map <MyKeyObject, MyData> _myDataHashMap;
_myDataHashMap[ a ] = b;
Run Code Online (Sandbox Code Playgroud)

我得到了大量的错误.这是前三个......

错误1错误C2784:'bool std :: operator <(const std :: _ Tree <_Traits>&,const std :: _ Tree <_Traits>&)':无法推断'const std :: _ Tree <_Traits>的模板参数&'from'const MyKeyObject'c:\ program files\microsoft visual studio 8\vc\include\functional 143

错误2错误C2784:'bool std :: operator <(const std :: basic_string <_Elem,_Traits,_Alloc>&,const _Elem*)':无法推断'const std :: basic_string <_Elem,_Traits的模板参数, _Alloc>&'from'const Tasking :: MyKeyObject'c:\ program files\microsoft visual studio 8\vc\include\functional 143

错误3错误C2784:'bool std :: operator <(const _Elem*,const std :: basic_string <_Elem,_Traits,_Alloc>&)':无法从'const MyDataObject'中推断'const _Elem*'的模板参数:\ program files\microsoft visual studio 8\vc\include\functional 143

...

如果我将键设置为像int一样简单的东西,那么一切都很好.

我究竟做错了什么?!也许我需要用模板做些什么?

是否有更好(更快?)的方式使用这样的自定义密钥对象访问数据?

Mar*_*ius 2

尝试以下方法,在 VS 2005 中为我工作。这是针对 stdext 命名空间中 VS2005 内置 hash_map 类型以及 boost unordered_map (首选)的解决方案。删除不使用的内容。

#include <boost/unordered_map.hpp>
#include <hash_map>

class HashKey
{
public:
    HashKey(const std::string& key)
    {
        _key=key;
    }
    HashKey(const char* key)
    {
        _key=key;
    }

    // for boost and stdext
    size_t hash() const
    {
        // your own hash function here
        size_t h = 0;
        std::string::const_iterator p, p_end;
        for(p = _key.begin(), p_end = _key.end(); p != p_end; ++p)
        {
            h = 31 * h + (*p);
        }
        return h;
    }
    // for boost
    bool operator==(const HashKey& other) const
    {
        return _key == other._key;
    }

    std::string _key;
};

// for boost
namespace boost
{
    template<>
    class hash<HashKey>
    {
    public :
        std::size_t operator()(const HashKey &mc) const
        {
            return mc.hash();
        }
    };
}

// for stdext
namespace stdext
{
    template<>
    class hash_compare<HashKey>
    {
    public :
        static const size_t bucket_size = 4;
        static const size_t min_buckets = 8;

        size_t operator()(const HashKey &mc) const
        {
            return mc.hash();
        }

        bool operator()(const HashKey &mc1, const HashKey &mc2) const
        {
            return (mc1._key < mc2._key);
        }
    };
}

int _tmain(int argc, _TCHAR* argv[])
{
    {
        stdext::hash_map<HashKey, int> test;
        test["one"] = 1;
        test["two"] = 2;
    }

    {
        boost::unordered_map<HashKey, int> test(8); // optional default initial bucket count 8
        test["one"] = 1;
        test["two"] = 2;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)