C++ Zero-Cost Abstractions
Core Question
When do we determine the type?
- •Compile Time (Static): Templates, Concepts, CRTP. Zero runtime cost, larger binary.
- •Runtime (Dynamic): Virtual functions,
std::any,std::variant. Flexible, vtable overhead.
Error → Design Question
| Issue | Design Question |
|---|---|
| Template spew | Are you missing Concepts constraints? |
| Linker error | Did you define template in .cpp instead of .h? |
| Object slicing | Did you assign Derived to Base value? |
| Slow build | Are you overusing headers/templates? |
Thinking Prompt
- •
Is the set of types known at compile time?
- •Yes? → Templates or
std::variant. - •No? → Inheritance (Virtual functions).
- •Yes? → Templates or
- •
Do I need to store them in a list?
- •Homogeneous? →
std::vector<T>. - •Heterogeneous? →
std::vector<std::unique_ptr<Base>>orstd::vector<std::variant<...>>.
- •Homogeneous? →
- •
Does the interface match exactly?
- •Duck typing needed? → Templates (Concepts).
- •Strict hierarchy? → Inheritance.
Trace Up / Down
- •
Trace Up:
- •Issue: "Virtual function call is too slow in tight loop."
- •Cause: Indirect branch misprediction.
- •Fix: Switch to Static Polymorphism (CRTP or Templates) if types are known.
- •
Trace Down:
- •Intent: "I want a function that accepts anything that has
.draw()." - •Code (C++20):
void render(Drawable auto& item) { item.draw(); }
- •Intent: "I want a function that accepts anything that has
Quick Reference
| Pattern | Dispatch | Cost | Use When |
|---|---|---|---|
virtual | Dynamic | Vtable + Cache miss | Plugins, Runtime extensions. |
| Template | Static | Code bloat | High perf, Type deduction. |
std::function | Dynamic | Alloc + Indirect | Storing callbacks. |
std::variant | Static branching | Branch switch | Closed set of types. |
| CRTP | Static | Zero | Static inheritance. |