The Curiously Recurring Template Pattern is an idiom in which a class X
derives from a class template Y
, taking a template parameter Z
, where Y
is instantiated with Z = X
. For example,
template<class Z> class Y {}; class X : public Y<X> {};
CRTP may be used to implement "compile-time polymorphism", when a base class exposes an interface, and derived classes implement such interface.
#include <cstdio> #ifndef __cpp_explicit_this_parameter // Traditional syntax template <class Derived> struct Base { void name() { (static_cast<Derived*>(this))->impl(); } }; struct D1 : public Base<D1> { void impl() { std::puts("D1::impl()"); } }; struct D2 : public Base<D2> { void impl() { std::puts("D2::impl()"); } }; void test() { // Base<D1> b1; b1.name(); //undefined behavior // Base<D2> b2; b2.name(); //undefined behavior D1 d1; d1.name(); D2 d2; d2.name(); } #else // C++23 alternative syntax; https://godbolt.org/z/s1o6qTMnP struct Base { void name(this auto&& self) { self.impl(); } }; struct D1 : public Base { void impl() { std::puts("D1::impl()"); } }; struct D2 : public Base { void impl() { std::puts("D2::impl()"); } }; void test() { D1 d1; d1.name(); D2 d2; d2.name(); } #endif int main() { test(); }
Output:
D1::impl() D2::impl()
(C++11) | allows an object to create a shared_ptr referring to itself (class template) |
(C++20) | helper class template for defining a view , using the curiously recurring template pattern (class template) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/crtp