tipos sirve que programacion parametros para funciones ejemplos datos con caracteristicas c++ templates metaprogramming template-meta-programming

sirve - ¿Cuáles son los mejores ejemplos de metaprogramación que ha visto en C++?



programacion c++ pdf (10)

Esta pregunta existe porque tiene un significado histórico, pero no se considera una buena pregunta sobre el tema para este sitio, así que no la use como evidencia de que puede hacer preguntas similares aquí.

Más información: https://stackoverflow.com/faq

¿Cuáles son los mejores ejemplos de metaprogramación que ha visto en C ++?
¿Cuáles son algunos usos prácticos de la metaprogramación que ha visto en C ++?


El mejor ejemplo de metaprogramación: engañar al compilador para que compute una lista de números primos. No es muy práctico, pero impresionante.

Un uso práctico son las sentencias assert de tiempo de compilación, es decir, que causan un error de compilación si una condición booleana no se cumple.


El uso más práctico de meta programación es convertir un error de tiempo de ejecución en un error de tiempo de compilación.

Ejemplo: Permite llamar a la interfaz IFoo. Uno de mis programas trataba sobre un objeto COM que tenía múltiples rutas a IFoo (jerarquía de herencia muy complicada). Desafortunadamente, la implementación subyacente del objeto COM no se dio cuenta de que tenían múltiples rutas a IFoo. Supusieron que siempre era la izquierda más uno. Entonces, dentro de su código, el siguiente patrón era muy común

void SomeMethod(IFoo* pFoo) { CFooImpl *p = (CFooImpl)pFoo; }

El segundo IFoo causó que el puntero "p" resultante fuera completamente inválido (la herencia múltiple es peligrosa).

La solución a largo plazo era que el propietario del objeto COM solucionara este problema. A corto plazo, aunque necesitaba asegurarme de que siempre devolvía el IFoo correcto. Podría garantizar que tuve el IFoo apropiado al usar una QI y evitar cualquier conversión implícita a IFoo. Así que creé una nueva implementación CComPtr <> y agregué la siguiente sustitución al método igual.

template <typename T> CComPtr<T>& operator=(const T* pT) { // CComPTr Assign logic } template <> CComPtr<IFoo> operator=<IFoo>(const IFoo* pT) { COMPILE_ERROR(); }

Esto reveló rápidamente cada lugar que impliqué implícitamente a IFoo.


Tendría que decir Boost.Lambda, Boost.Function y Boost.Bind y la forma en que todos funcionan perfectamente juntos. Proporcionan una interfaz realmente ingeniosa y hacen que la programación funcional sea lo más fácil posible en un lenguaje que en realidad no fue creado.


luabind es un ejemplo práctico muy bueno, un enlace dsl bastante bueno para unir clases de C ++ a lua




Blitz ++ hace algunas cosas impresionantes con las plantillas (por ejemplo, una sola línea de código legible se puede convertir en un conjunto de bucles sobre una matriz multidimensional, optimizada automáticamente para la mejor orden transversal).


Personalmente, creo que Boost.Spirit es un ejemplo bastante sorprendente de meta-programación. Es un generador de analizador completo que le permite expresar gramáticas utilizando la sintaxis de C ++.


No es de uso práctico (excepto tal vez para las pruebas de compilación), pero metatrace es un rastreador de rayos Whitted-Style (es decir, recursivo y determinista) que genera imágenes como las que se encuentran en el momento de la compilación:

Algunas partes más complejas del código se pueden ver en fixp.hh , que tiene una implementación de sqrt de punto fijo utilizando el método Heron, o sphere.hh que muestra el cálculo de intersección de rayos / esferas.


Hace poco planteé una pregunta: C ++ Runtime Knowledge of Classes y la respuesta que recibí de un usuario de "Denice" era una URL para un sitio web Meatspace: C ++ runtime class registration .

Creo que es una forma genial de utilizar plantillas y crear instancias de objetos que se derivan de una clase base, de modo que cuando tengo 10 archivos C ++, todos pueden simplemente agregar AUTO_REGISTER_BASE () en la parte inferior, y cuando todo es todo hecho y vinculado, solo las clases / archivos que lo hicieron se registrarían, por lo que en el tiempo de ejecución puede cambiar entre las diferentes clases que están disponibles, y las que no están disponibles no se registran y por lo tanto no se pueden llamar accidentalmente.

Hay muchas maneras diferentes de hacer notificaciones de eventos (seleccionando (), kqueue (), / dev / epoll, Solaris tiene sus propias cosas, poll ()), y necesitaba una forma de tener todos los archivos de clase en el directorio, pero dependiendo de qué sistema operativo se ejecutó Makefile, solo compilaría algunos. Necesitaba una manera de saber en tiempo de ejecución cuáles estaban disponibles, y tenía una forma para que el programador utilizara la biblioteca para seleccionar sus preferencias, sin embargo, si no estaba disponible, simplemente usaba el que tenía el sentido más lógico para la plataforma (cada uno tener pesos asignados a ellos).

El código anterior me ayudó a lograr este objetivo, con algunas modificaciones importantes, ¡pero me ayudó de todos modos!