HeadlinesBriefing favicon HeadlinesBriefing.com

C++26 Reflection Type Erasure with rjk::duck

Hacker News •
×

rjk::duck leverages C++26 reflection to eliminate boilerplate in type erasure. Instead of writing 100+ lines or using heavy libraries like Boost.TypeErasure or Folly.Poly, you declare an interface once with the [[=rjk::trait]] annotation:

```cpp

struct [[=rjk::trait]] Container {

auto size() const -> std::size_t;

auto empty() const -> bool;

auto clear() -> void;

};

rjk::duck<Container> c{std::vector<int>{1, 2, 3}};

c.size(); // 3

c = std::string{"hello"};

c.size(); // 5

```

The ^^ operator produces reflections (`std::meta::info`) queried via `annotations_of` and `type_of`. Tag generation transforms trait members into `has_fn<name, signature>` tags using `members_of`, `identifier_of`, and `substitute`.

Vtable generation occurs in a consteval block using `define_aggregate` and template for expansion statements. Function pointers are created for each trait member, with the splice operator (`[: expr :]`) assigning actual function pointers. `make_vtable<T>()` matches type members to vtable slots via reflection.

Overload resolution and `convert_to_vtable_func` handle the erasure mechanics, turning member functions into callable `void*` signatures. The library remains a single header, requiring GCC with `-std=c++26 -freflection`.