首页 > 解决方案 > 如何将 boost::unordered_set 与自定义类一起使用?

问题描述

我很难调用 hash_value。从这篇文章中,我想申请vector<vector<E>>E 是一个自定义对象。我的代码如下:

struct E;
class myclass {
private:
     vector<E> lhs;
public:
    myclass(const vector<E>& v) :lhs{ v } {  };
    static size_t hash_value(const vector<E>& v) {
      size_t seed = 0;
         boost::hash_combine(seed, d.name);
         boost::hash_combine(seed, d.scope);
      return seed;
    }
    bool operator==(const vector<E> >& rhs) {
       for (unsigned i = 0; i < lhs.size(); i++)
         if (lhs[i].name != rhs[i].name || lhs[i].scope!= rhs[i].scope)
             return false;
       return true;
    };
};

然后我调用这个代码:

void test(std::vector<std::vector<E>>& A)
{
    boost::unordered_set < myclass > input_records(A.size());
    
    for (BOOST_AUTO(it, A.begin()); it != (A.end());) {
      auto k = input_records.insert(myclass{*it}); <<--
      ....
    }
}

但是我收到一个错误:

在此处输入图像描述

此外,在某些情况下,此代码会执行,但从未调用 hash_value。我不确定我错过了什么?

我该如何解决?

标签: c++boost

解决方案


您正在尝试使用boost::unordered_set<myclass>,它将在内部使用boost::hash<myclass>,它将在与通过Argument-Dependent Lookuphash_value(myclass)相同的名称空间中查找函数。您使您成为 的非静态成员,因此将无法找到它。但即使可以,它也希望您将单个对象作为参数,而不是.myclasshash_value()myclassboost::hashhash_value()myclassvector

请参阅扩展 boost::hash 以了解Boost 文档中的自定义数据类型。

此外,一个类与另一个对象operator==进行比较。*this在 内部myclass,您operator==应该将单个myclass对象作为参数,而不是vector.

试试这个:

struct E {
    string name;
    int scope;
};

size_t hash_value(const E& obj) {
    std::size_t seed = 0;
    boost::hash_combine(seed, obj.name);
    boost::hash_combine(seed, obj.scope);
    return seed;
}

class myclass {
private:
    vector<E> vec;
public:
    myclass(const vector<E>& v) : vec(v) {}

    bool operator==(const myclass& rhs) const {
       // vector has its own operator== for comparing elements in its array...
       return vec == rhs.vec;
    }

    friend size_t hash_value(const myclass& obj) {
        return boost::hash_range(obj.vec.begin(), obj.vec.end());
    }
};
void test(std::vector<std::vector<E>>& A)
{
    boost::unordered_set<myclass> input_records(A.size());
    
    for (BOOST_AUTO(it, A.begin()); it != (A.end());) {
      auto k = input_records.insert(*it);
      ...
    }
}

推荐阅读