Annotations for C++26 Hashing -- Krystian Piękoś

Static reflection already makes generic hashing in C++26 far more expressive, but annotations push it into genuinely ergonomic territory. By letting types explicitly opt-in to hashing and allowing individual members or base classes to be cleanly excluded, we get a solution that is both powerful and readable.

Annotations for C++26 Hashing

by Krystian Piękoś

From the article:

In my recent post, I demonstrated how to use static reflection from C++26 to implement generic hash computation for custom types. Let's review the final implementation. The core of the solution is the calculate_hash() function, which iterates over sub-objects (including both base classes sub-objects and class/struct non-static data members) to compute a combined hash.

template <typename T>
concept Hashable = requires {
  { std::hash<T>{}(std::declval<T>()) } -> std::convertible_to<size_t>;
};

template <typename T>
  requires std::is_class_v<T>
size_t calculate_hash(const T& obj, size_t seed = 0)
{
  constexpr auto ctx = std::meta::access_context::unchecked();

 
  static constexpr auto r_subobjects = std::define_static_array(std::meta::subobjects_of(^^T, ctx));

  template for (constexpr auto r_sub : r_subobjects)
  {
    using Subobject_t = typename[:std::meta::type_of(r_sub):];
    static_assert(Hashable<Subobject_t>, "Subobject must be hashable");
    Utility::hash_combine(seed, obj.[:r_sub:])
  }

  return seed;
}

Add a Comment

Comments are closed.

Comments (0)

There are currently no comments on this entry.