About using concepts:

 

Concepts allow to specify required members, but it is actually more like a boolean test than an interface signature specification.

 

One either specifies

 - that the feature demands some suitable concept definition, has to be well-formed for std::any<concept> or

 - makes it clear(er) in syntax/C++ language that this is an interface

 - separates the member list/interface
from the concept, perhaps not all members should get a dispatch entry
 

 

Will this work only on public members, with any access specifier or at a certain point in the program there has to be allowed access, e.g. at the constructor call of std::any?

 

The logical point would be, wherever the members are called, but at that point the class is not known at compile-time, only the dispatch is used.

 

-----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