Could you say, what happens under the hood in rough terms?

 

In your example, you used it as template and element type for std::vector.

So it is most similar to std::any. The typeid is stored and the object is put on the heap, as the maximum size cannot be known (e.g. compared to std::optional)

 

You want to directly access members, especially member functions, which are specified in the concept.

So depending on the typeid the respective offset is determined.

 

There is no inheritance with virtual functions.

 

We can put pointers into the new std::any<concept> type and fill those at the time of construction. Is this your mentioned dispatch table? The construction would work like a compile time templated function. That is the only way to cover a possibly infinite number of types fulfilling the concept.

 


 

-----Ursprüngliche Nachricht-----
Von: amngis_21d38 via Std-Proposals <std-proposals@lists.isocpp.org>
Gesendet: So 17.05.2026 05:05
Betreff: [std-proposals] Interest check: Constrained runtime type erasure via concepts
An: std-proposals@lists.isocpp.org;
CC: amngis_21d38 <amngis_21d38@163.com>;
 
 
 
 
Hi all,
 
I'd like to gauge interest in a language/library feature that bridges C++20
concepts with runtime polymorphism.
 
**Problem:**
C++20 gives us powerful compile-time concepts, but when we need to store
heterogeneous types in a container (e.g., a vector of "anything drawable"),
we must choose between:
- Templates (no runtime flexibility)
- Manual type-erasure boilerplate (Sean Parent's runtime concept pattern, ~50+ lines per interface)
- std::any (unsafe any_cast, no interface enforcement)
 
**Idea:**
Introduce a concept-constrained erased type, spelled std::any<<Concept> or
std::dyn<<Concept>, which:
- Accepts only types satisfying the concept (compile-time check)
- Exposes the concept's required members as directly callable methods
- Requires no inheritance, no virtual functions, no manual vtable authoring
 
Example:
  template<typename T>
  concept Drawable = requires(T t) { t.draw(); };
 
  std::vector<std::any<<Drawable>> scene;
  scene.emplace_back(Circle{1.0});      // OK, satisfies Drawable
  scene.emplace_back(Rectangle{2.0, 3.0});// OK
  // scene.emplace_back(42);            // Error: int does not satisfy Drawable
 
  for (auto& s : scene) {
      s.draw();                         // Direct call. No any_cast.
  }
 
**Prior art:**
- Rust's dyn Trait, Swift protocols, Go interfaces (non-intrusive runtime
  polymorphism with compiler-generated witness tables)
- Library approximations: woid, dyno, te (but require heavy boilerplate or
  macros)
 
**Questions for the group:**
1. Has this direction been discussed before in EWG/LEWG?
2. Is there appetite for a core-language mechanism to auto-generate dispatch
   tables from concept requirements, or would a pure-library solution based
   on reflection (P2996) be preferred?
3. Should this overload std::any<<Concept> or introduce a new vocabulary type
   (std::dyn<<Concept>)?
 
I have a more detailed draft if there is interest. Thanks for your time!
-- 
 Std-Proposals mailing list
 Std-Proposals@lists.isocpp.org
 https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals