P3816R2 - Hashing meta::info WG21
Posted by u/reflection_enjoyer_26 · 7 hr. ago

Authors: Matt Cummins, Valentyn Yukhymenko
Document: P3816R2
Date: 2026-01-13
Target: SG7, LEWG, EWG
Link: wg21.link/p3816r2

P2996 gave us meta::info for reflection. P3372 made unordered containers constexpr. P3816 fills the gap between them: you still can't use meta::info as a key in an unordered_map because there's no hash for it.

This paper proposes consteval_hash<meta::info> - a new class template specifically for compile-time hashing, separate from std::hash. The argument is that specializing std::hash doesn't work cleanly because hash has runtime requirements inconsistent with consteval-only types. So instead we get a parallel hash type that lives entirely at compile time.

The design settles on "semi-stable" semantics - hash values are stable across repeated compilations of the same source but may change if the source changes. There's a discussion of ABI implications and a table of twelve alternative names they considered and rejected. R2 tidies up the motivation section and adds an annotations example.

▲ 38 points (92% upvoted) · 7 comments
sorted by: best
u/constexpr_all_the_things 23 points 2 hr. ago

Nice to see the reflection plumbing papers keep landing. The mp_unique example is exactly the kind of thing you want to be able to write without gymnastics.

u/template_archaeologist 11 points 4 hr. ago

The interesting design choice here is the semi-stable hash. From the paper:

The value shall be stable across repeated compiler runs. [ Note: Modifying the source code may change the value. — end note ]

This is a meaningful middle ground. An unstable hash (just hash the AST pointer) is trivial to implement but kills reproducible builds. A fully stable hash requires the compiler to derive a value from the semantic identity of the reflection - name, scope, parameter types - which is expensive and fragile as the language adds new reflectable constructs.

Semi-stable sidesteps both by interning: assign each AST node a deterministic integer ID from a counter as you encounter it. Same source, same traversal order, same IDs, same hashes. Change the source, the traversal changes, IDs shift. It's the approach from their second clang-p2996 PR and it's clever.

The question I'd have for LEWG is whether users will accidentally depend on cross-TU stability that isn't guaranteed. The paper's ABI section has a somewhat contrived example with buffer sizes, but the real risk is someone stashing hash values into a constexpr variable in a header and expecting the same value in every TU that includes it.

u/daily_driver_dev 5 points 3 hr. ago

Honest question - who is stashing compile-time hash values into headers? The intended use case is keying an unordered_map inside a consteval function. The hash never escapes the constant evaluator. The ABI scenario in the paper requires you to go out of your way to do something weird with the value.

u/naming_is_hard_42 18 points 1 hr. ago

Table of twelve rejected names is the real content of this paper. I lost it at:

Although we love Zig, we are proposing a C++ feature!

consteval_hash is fine. Move on, LEWG.

u/hashmap_heretic 7 points 5 hr. ago

Because of the runtime requirements on hash<T>, existing specializations cannot be made constexpr

But meta::info is already consteval-only. There are no runtime requirements to conflict with. You could specialize hash<meta::info> as consteval and it would be perfectly consistent - you can't use meta::info at runtime anyway.

The argument for a separate type only holds if you plan to extend consteval_hash to types that do have runtime hash specializations (int, string, etc.). Section 9 confirms that's the plan. So this is really a paper about creating a parallel compile-time hash framework, not about hashing meta::info. The title undersells it.

u/just_a_library_author 4 points 6 hr. ago

Scope note: Section 9.1 proposes extending consteval_hash to all arithmetic, enum, and pointer types. Section 9.2 proposes adding a template parameter for randomized vs stable hashing. That's a significant expansion from "hash meta::info for unordered containers."

I'd expect LEWG to ask them to split - ship the meta::info specialization now, iterate on the broader framework in a follow-up. That's how P2996 itself progressed: narrow scope first, extensions later.

u/waiting_for_cpp26 14 points 47 minutes ago

Every time I see a paper that depends on P2996 and P3372 I have to check - are those actually in C++26 yet? checks okay yes they are. We're building on top of things that exist now. Progress.