1

I would like to hash a class that has two private members e.g.:

foo.h

class Foo {
    private:
        std::string a;
        std::string b;

    public:
        Foo (std::string a, std::string b);
        bool operator==(const Foo& other) const;
        bool operator!=(const Foo& other) const;
        std::size_t operator()(const Foo& ) const;
};

namespace std {
    template <> struct hash<Foo> {
        std::size_t operator()(const Foo& cp) const;
    };
}

foo.cpp

Foo::Foo (std::string _a, std::string _b) {
    this->a = _a;
    this->b = _b;
}

bool Foo::operator== (const Foo& other) const {
    return this->a == other.a && this->b == other.b;
}

bool Foo::operator!= (const Foo& other) const {
    return !operator==(other);
}

std::size_t std::hash<Foo>::operator()(Foo const& foo) const {
    std::string f = foo.a; // << This wont compile!
    return 1;
}

In C++ how is hashing of Foo typically done when that final hash function doesn't have access to the private member of foo.

Feel free to include boost or abseil in your answer.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Luke
  • 884
  • 8
  • 21
  • 3
    What if Foo had a public member function called `std::size_t get_hash() const;` ...? – Eljay Mar 24 '21 at 22:31
  • 2
    You can use a `friend` declaration (note that [this requires forward-declaring](https://stackoverflow.com/a/10934412/1968) both your class and the `std::hash` specialisation). That’s IMHO better than polluting the interface by adding another unnecessary member function. – Konrad Rudolph Mar 24 '21 at 22:33

1 Answers1

6

What you can do is declare std::hash<Foo> as a friend of Foo:

class Foo {
 private:
  std::string a;
  std::string b;

 public:
  Foo(std::string a, std::string b);
  bool operator==(const Foo& other) const;
  bool operator!=(const Foo& other) const;
  std::size_t operator()(const Foo&) const;

  friend std::hash<Foo>;
};
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Yamahari
  • 1,926
  • 9
  • 25