C++ 存储C+的有效方法+;在std::set/std::map中具有多个不同类型字段的对象

C++ 存储C+的有效方法+;在std::set/std::map中具有多个不同类型字段的对象,c++,stl,operator-overloading,stdmap,stdset,C++,Stl,Operator Overloading,Stdmap,Stdset,我有一个一般性问题。假设我有一个C++类,它有多个不同类型的字段。我希望/需要将此类的对象存储在std::set或std::map中(以便在O(log(N))中访问它们) 为了做到这一点,我需要重载操作符,您可以创建自己的哈希函数,将类成员作为参数,然后使用这些哈希值作为键将对象存储在or结构中。这样您就不用麻烦将新对象和映射中的所有对象进行比较。您也可以用于此特定目的。 您可以专门化用户定义类的std::hash(从): #包括 #包括 #包括 结构 { std::string first_n

我有一个一般性问题。假设我有一个C++类,它有多个不同类型的字段。我希望/需要将此类的对象存储在
std::set
std::map
中(以便在O(log(N))中访问它们)


为了做到这一点,我需要重载
操作符,您可以创建自己的哈希函数,将类成员作为参数,然后使用这些哈希值作为键将对象存储在or结构中。这样您就不用麻烦将新对象和映射中的所有对象进行比较。您也可以用于此特定目的。

您可以专门化用户定义类的std::hash(从):

#包括
#包括
#包括
结构
{
std::string first_name;
std::字符串last_name;
};
名称空间标准
{
模板
结构散列
{
typedef的参数类型;
typedef std::大小\u t结果\u类型;
结果类型运算符()(参数类型常量&s)常量
{
结果类型常量h1(std::hash()(s.first_name));
结果类型常量h2(std::hash()(s.last_name));

返回h1^(h2您的问题实际上更像是一个三个问题:


我需要重载
操作符您考虑过使用tuple吗

// Multi-index map
map<tuple<int, char, float>, string> m;
m[make_tuple(31, 'd', 23.5f)] = "Just an idea";
//多索引映射
地图m;
m[make_tuple(31,'d',23.5f)]=“只是一个想法”;

如果它们没有自然顺序,你想在地图中存储它们吗?如果没有任何意义,为什么要使用关联容器进行排序?@JerryCoffin为了在O(log(N))中访问它们,你打算使用什么特征来查找它们?@AlexLop。这并不能真正回答任何问题。是否存在(例如)这就是为什么不能将它们存储在向量中,然后在O(1)中访问它们的原因?最好使用
std::unordered_map
,这会导致散列冲突。你知道这种“散列”对两个不同对象返回相同结果的概率是多少吗?另外,如果我有许多字段,为每种类型定义散列函数,那么计算整个对象的一般散列可能比“按字段比较的本机字段。@AlexLop.,散列函数返回相当高的整数值,因此不会有太大问题。感谢您的详细回答。我没有提到它,但我有一个限制。C++11目前不适用于我,这就是为什么我提到
std::map
/
std::set
,而不是他们的C++11”unord但是我不熟悉
std::tie
,它看起来比许多
if(…)else…
条件更具可读性,因此对我来说似乎是可行的。但它也仅在C++11上可用。
#include <iostream>
#include <functional>
#include <string>

struct S
{
    std::string first_name;
    std::string last_name;
};

namespace std
{
    template<>
    struct hash<S>
    {
        typedef S argument_type;
        typedef std::size_t result_type;

        result_type operator()(argument_type const& s) const
        {
            result_type const h1 ( std::hash<std::string>()(s.first_name) );
            result_type const h2 ( std::hash<std::string>()(s.last_name) );
            return h1 ^ (h2 << 1);
        }
    };
}

int main()
{
    S s;
    s.first_name = "Bender";
    s.last_name =  "Rodriguez";
    std::hash<S> hash_fn;

    std::cout << "hash(s) = " << hash_fn(s) << "\n";
}
bool myComparer(const MyStruct &a, const MyStruct &b) {
    return std::tie(a.member1, a.member2, a.member3) < std::tie(b.member1, b.member2, b.member3);
}
// Multi-index map
map<tuple<int, char, float>, string> m;
m[make_tuple(31, 'd', 23.5f)] = "Just an idea";