Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement hash for custom class C++

Tags:

c++

c++11

I have a circle defined like so:


class Circle {
public:
    int x;
    int y;
    int r;

    Circle() : x(0), y(0), r(0) {}

    Circle(int x, int y, int r) {
        this->x = x;
        this->y = y;
        this->r = r;
    }

    double area() {
        return PI * pow(r, 2);
    }
};

I want to be able to add it to a set, based on the hash of its center (x and y)

What's the correct and idiomatic way of doing this in C++ 11?

My question is two-fold

(1) Is there a way I can ask C++ to hash it for me? In Kotlin, there is the notion of a dataclass which automatically hashes the class attributes. I am looking for something similar.

(2) If not, how do I hash it myself, and relatedly - what are operators I need to overload?

like image 463
nz_21 Avatar asked Oct 18 '25 13:10

nz_21


1 Answers

I want to be able to add it to a set, based on the hash of its center (x and y)

If you wan't to put your circle in the std::set, you don't need to provide a hash function. You need to provide it only if you'd like to use std::unordered_set or any other unordered associative container (more info in hash).

As it goes for the most idiomatic way of implementation, I would go with something like this (taken from the std::hash example):

#include <cmath>
#include <unordered_set>
#include <set>

class Circle {
public:
    int x;
    int y;
    int r;

    Circle() : x(0), y(0), r(0) {}

    Circle(int x, int y, int r) {
        this->x = x;
        this->y = y;
        this->r = r;
    }

    double area() {
        return 3.1415 * pow(r, 2);
    }
};

bool operator==(const Circle& lhs, const Circle& rhs) {
    return lhs.x == rhs.x && lhs.y == rhs.y;
}

template<> struct std::hash<Circle> {
    std::size_t operator()(Circle const& s) const noexcept {
        std::size_t h1 = std::hash<int>{}(s.x);
        std::size_t h2 = std::hash<int>{}(s.y);
        return h1 ^ (h2 << 1); // or use boost::hash_combine (see Discussion) https://en.cppreference.com/w/Talk:cpp/utility/hash
    }
};

int main() {
    std::unordered_set<Circle> circles;
    return 0;
}

Link to example

EDIT:

(1) Is there a way I can ask C++ to hash it for me? In Kotlin, there is the notion of a dataclass which automatically hashes the class attributes. I am looking for something similar.

There is hash function for the basic types (list is on std::hash). You need to provide hashing function for your custom type. You can take an inspiration from the cppreference or create an own hashing function.

like image 125
borievka Avatar answered Oct 20 '25 02:10

borievka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!