CRTP (Curiously Recurring Template Pattern)
Use case
Implement common functionality for memory region types without virtual function overhead.
Explanation
CRTP provides static polymorphism: a base class template takes the derived class as a parameter, enabling compile-time method dispatch (via static_cast). Zero runtime overhead compared to virtual functions (at the cost of increased binary size).
Code
#include <cstdint>
#include <print>
template <typename Derived> class MemoryRegion {
public:
void dump() const {
// Dereference this, then cast the base reference to derived reference.
const auto &self = static_cast<const Derived &>(*this);
std::println("{}: {:#x}", self.name(), self.start());
}
};
class CodeSection : public MemoryRegion<CodeSection> {
uint64_t base_;
public:
CodeSection(uint64_t base) : base_(base) {}
uint64_t start() const { return base_; }
const char *name() const { return ".text"; }
};
class DataSection : public MemoryRegion<DataSection> {
uint64_t base_;
public:
DataSection(uint64_t base) : base_(base) {}
uint64_t start() const { return base_; }
const char *name() const { return ".data"; }
};
int main() {
CodeSection text{0x10001000};
DataSection data{0x10002000};
text.dump();
data.dump();
return 0;
}
Output
$ ./src/design-patterns-and-idioms/build/crtp
.text: 0x10001000
.data: 0x10002000