¿Cómo puedo usar CRTP en C ++ para evitar la sobrecarga de las funciones de miembros virtuales?
89
Hay dos maneras.
El primero es especificando la interfaz estáticamente para la estructura de tipos:
template <class Derived>
struct base {
void foo() {
static_cast<Derived *>(this)->foo();
};
};
struct my_type : base<my_type> {
void foo(); // required to compile.
};
struct your_type : base<your_type> {
void foo(); // required to compile.
};
La segunda es evitar el uso del lenguaje de referencia a base o puntero a base y hacer el cableado en tiempo de compilación. Usando la definición anterior, puede tener funciones de plantilla que se parecen a estas:
template <class T> // T is deduced at compile-time
void bar(base<T> & obj) {
obj.foo(); // will do static dispatch
}
struct not_derived_from_base { }; // notice, not derived from base
// ...
my_type my_instance;
your_type your_instance;
not_derived_from_base invalid_instance;
bar(my_instance); // will call my_instance.foo()
bar(your_instance); // will call your_instance.foo()
bar(invalid_instance); // compile error, cannot deduce correct overload
Por lo tanto, la combinación de la definición de estructura / interfaz y la deducción de tipo en tiempo de compilación en sus funciones le permite realizar un envío estático en lugar de un envío dinámico. Ésta es la esencia del polimorfismo estático.
not_derived_from_base
no se derivabase
ni se deriva debase
...Yo mismo he estado buscando discusiones decentes sobre CRTP. Las técnicas de Todd Veldhuizen para C ++ científico son un gran recurso para esto (1.3) y muchas otras técnicas avanzadas como las plantillas de expresión.
Además, descubrí que se podía leer la mayoría de los artículos de Gemas C ++ originales de Coplien en Google Books. Quizás ese todavía sea el caso.
fuente
dynamic_cast
o métodos virtuales.Tuve que buscar CRTP . Sin embargo, habiendo hecho eso, encontré algunas cosas sobre el polimorfismo estático . Sospecho que esta es la respuesta a tu pregunta.
Resulta que ATL usa este patrón de manera bastante extensa.
fuente
Esta respuesta de Wikipedia tiene todo lo que necesita. A saber:
Aunque no sé cuánto te compra esto realmente. La sobrecarga de una llamada de función virtual es (dependiente del compilador, por supuesto):
Mientras que la sobrecarga del polimorfismo estático CRTP es:
fuente