Indexed summary. This entry is an agent-written synopsis of an article first published at sofiabelen.github.io. Read the original for the full text.
The author's explicit goal is to understand Rust not by drawing 1:1 parallels with C++ but by probing the why of its design choices. Starting with two C++ approaches to polymorphism, virtual functions and CRTP, the post builds toward Rust's dyn Trait by examining what static dispatch can and cannot express.
Key points
- Static dispatch (generics and monomorphization) generates a separate compiled function per concrete type; zero runtime cost but types must be known at compile time.
- Rust's zero-sized types, structs with no fields, have a
size_ofof 0, unlike C++ where every object must have at least 1 byte for unique address guarantees. Rust tracks identity through ownership rather than memory addresses. &dyn Drawis a wide pointer: 16 bytes on 64-bit systems, comprising a data pointer and a vtable pointer. The vtable holds the specificdraw()implementation to call at runtime.- The dispatch choice is made at the call site, not the type definition, which differs from C++ where marking a method
virtualcommits the class to dynamic dispatch. Vec<Box<dyn Draw>>is the idiomatic way to hold a heterogeneous collection in Rust;Box<dyn Trait>has uniform size because it is always a wide pointer.- Object safety rules, no methods returning
Self, no generic method parameters, exist because the compiler cannot know the concrete type at runtime to allocate the correct return size.