Espacios de nombres
Variantes
Acciones

Patrón de plantilla curiosamente recurrente (CRTP)

De cppreference.com
< cpp‎ | language
 
 
Lenguaje C++
Temas generales
Control de flujo
Instrucciones de ejecución condicionales
Instrucciones de iteración (bucles)
Declaraciones de salto
Funciones
Declaración de funciones
Declaración de funciones lambda
Especificador inline
Especificación de excepciones(hasta C++20)
Especificador noexcept(C++11)
Excepciones
Espacios de nombres
Tipos
Especificadores
decltype(C++11)
auto(C++11)
alignas(C++11)
Especificadores de duración de almacenamiento
Inicialización
Expresiones
Representaciones alternas
Literales
Booleanos - Enteros - De punto flotante
De carácter - De cadena - nullptr(C++11)
Definidos por el usuario(C++11)
Utilidades
Atributos(C++11)
Tipos
Declaración de typedef
Declaración de alias de tipo(C++11)
Conversiones
Conversiones implícitas - Conversiones explícitas
static_cast - dynamic_cast
const_cast - reinterpret_cast
Asignación de memoria
Clases
Propiedades de funciones específicas de la clase
Funciones miembro especiales
Plantillas
Misceláneos
 

El patrón de plantilla curiosamente recurrente (o CRTP por sus siglas en inglés) es una expresión idiomática en la que una clase se deriva de una plantilla de clase Y, tomando un parámetro de plantilla Z, donde Y es instanciada con Z = X. Por ejemplo,

template<class Z>class Y {};   class X :public Y<X>{};

[editar]Ejemplo

CRTP puede usarse para implementar "polimorfismo en tiempo de compilación", cuando una clase base expone una interfaz, y las clases derivadas implementan tal interfaz.

#include <cstdio>   #ifndef __cpp_explicit_this_parameter // sintaxis tradicional   template<class Derivada>struct Base {void nombre(){(static_cast<Derivada*>(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.nombre(); // comportamiento indefinido// Base<D2> b2; b2.nombre(); // comportamiento indefinido D1 d1; d1.nombre(); D2 d2; d2.nombre();}   #else // sintaxis alternativa de C++23; https://godbolt.org/z/s1o6qTMnP   struct Base {void nombre(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.nombre(); D2 d2; d2.nombre();}   #endif   int main(){ test();}

Salida:

D1::impl() D2::impl()

[editar]Véase también

Permite a un objeto crear un puntero compartido (shared_ptr) refiriéndose a sí mismo.
(plantilla de clase)[editar]
Plantilla de clase auxiliar para definir una vista (view), usando el patrón de plantilla curiosamente recurrente (CRTP).
(plantilla de clase)[editar]
close